views:

33

answers:

2

I have a remote object exposed through RMI, which I use to perform several things on a resource that the object holds. Right now I have method for each operation I need to perform.

Example:

public interface IRobotController {
    public int walk(int meters);
    public void dance(int seconds);
}

public interface RMIRobotController implements IRobotController, java.rmi.Remote {}

public class RobotController implements RMIRobotController {
    private Robot robot;

    ...

    public int walk(int meters) {
        return robot.walk(meters);
    }

    public void dance(int seconds) {
        robot.dance(seconds);
    }
}

I would like refactor the API so that I would only have one method, operate(). Assume I don't want to return an actual reference to the robot object through RMI, because I sometimes need to perform more than one operation, and don't want the round trips.

I came up with this, based on the concept of Callable<T>:

public abstract class RobotCallable<T> {
    protected Robot robot;

    public void setRobot(Robot robot) {
        this.robot = robot;
    }

    public abstract T call()
}

public class RobotController implements RMIRobotController {
    private Robot robot;

    ...

    public T operate(RobotCallable<T> robotCallable) {
        robotCallable.setRobot(robot)
        return robotCallable.call();
    }
}

I this how these things are usually implemented? Is there some mechanism for RMI that does this automatically?

+1  A: 

What you are trying to do is called the Command Pattern.
The purpose to use this pattern is to reduce coupling.

That being said that is not really going to happen since your Serialization IDs will not match every time you make a change and compile.

You loose type safety when making your calls.

You have to implement your own message format, in which you put your payload and message marshall and then unmarshall it on arrival (This is typically done with XML these days).

Basically by using the Command Pattern with RMI, you loose all the benefits of RMI and just use it as a transport.

If this is your goal then WebServices would be a far better way to go.

Romain Hippeau
A: 

Why do you want to reduce the interface to one API? There's really little cost in supporting multiple remote methods in an interface: you only have to declare them, write them, and call them. No RMI overheads whatsoever. And you have to write the code to do each operation anyway, plus the code to despatch from operation() to the desired piece of code, which having separate methods would have done for you for nothing. And the result is much clearer.

EJP