my communication design - your opinions please

I have been thinking about how I should implement my communication. My plan is to use serialization and create a different serializable communication object for each task (getFieldInfo, getRecordCount, etc). Each object implements my Communicable interface

When an object is received at either end, the appropriate method is called together with these contexts which are I guess "mediators" in that they store the references I need to call. Here is an example of getting a record.

Does anyone see any problems with this? The number of Communicable classes will increase when extra functionality is added...is this bad? Anyone know any better ways of designing communication with sockets? [Andrew: put code inside [code] blocks] [ October 19, 2003: Message edited by: Andrew Monkhouse ]

Hi Blair, Please put your code inside UBB [code] and [/code] blocks - it makes your code much easier to read. I am curious - why don't you have your Communicable interface extend Serializable so that all the classes that implement Communicable automatically implement Serializable? The issue I see with your design is that for every request & response you will be sending a class with all it's methods over the network. This will result in greater bandwidth usage and slower responses. If you used a Transfer Object then you would be passing a much smaller, more generic object. All the Transfer Object contains is the data to be worked on and an indicator to say what the sender is sending. (For anyone reading this and trying to work out the difference between a "Transfer Object" and a "Value Object": Sun used to call the "Transfer Object" a "Value Object", (and their diagrams havent been updated )) Since your design will work, you might not be interested in the Transfer Object, so I have not gone into details ... yet Regards, Andrew [ October 19, 2003: Message edited by: Andrew Monkhouse ]

Also, giving this Command object responsibilities on both client and server seems a bit much to me. That means that any time you want to change anything on the client or the server, the Command classes will have to change. I think that makes it more brittle than it needs to be. I'd consider having a Command class for passing messages from client to server, and maybe a separate Response class for sending data from server to client. I don't think the server needs a way to initiate messages to the client; it just waits for commands, and responds. That may not be true for a more advanced system, but it's true here, I believe.

"I'm not back." - Bill Harding, Twister

blair cairns
Greenhorn

Joined: Oct 24, 2002
Posts: 8

posted Oct 20, 2003 01:53:00

0

Hi, Jim and Andrew, thanks for your constructive comments.

why don't you have your Communicable interface extend Serializable so that all the classes that implement Communicable automatically implement Serializable

That is the intention, just slipped my mind.

I'd consider having a Command class for passing messages from client to server, and maybe a separate Response class for sending data from server to client.

...resulting in a doubling in the number of classes. But I think you are right. My solution is too brittle.

I don't think the server needs a way to initiate messages to the client; it just waits for commands, and responds.

If the server does need to initiate a message, my messaging should be generic enough to do this. I was intending to use the same MessagingPort object (sends and receives messages) the client and the server.

If you used a Transfer Object then you would be passing a much smaller, more generic object.

I wasnt aware of the Value or Transfer Object Pattern in this context, I think its a good idea. The only drawback is that you have these horrible if or switch statements at either end to determine what sort of action it is. With a Command object, one simply needs to call performTask() and doesnt need to interpret it in a switch statement. The best solution would be a mix of both Command and Transfer objects. Regards, Blair

Hi Blair, Andrew and Jim,Andrew: The issue I see with your design is that for every request & response you will be sending a class with all it's methods over the network. This will result in greater bandwidth usage and slower responses. If you used a Transfer Object then you would be passing a much smaller, more generic object. All the Transfer Object contains is the data to be worked on and an indicator to say what the sender is sending. Three comments. When you send a serialized object, your are not "sending a class with all it's methods over the network", just its signatures IMO. The main purpose of TransferObject seems to be to avoid multiple remote calls just to access multiple individual attributes : "The client usually requires values for more than one attribute or dependent object from an enterprise bean. Thus, the client may invoke multiple remote calls to obtain the required data.". The context here is quite different : your client calls some executable command once, bringing with itself all the data needed to perform the task. If you really want to optimize the way your commands are serialized, look at the Externalizable interface. But if you use it, it will be at the cost of maintability.Jim: Also, giving this Command object responsibilities on both client and server seems a bit much to me. That means that any time you want to change anything on the client or the server, the Command classes will have to change. 100% agreed.Blair, quote:I'd consider having a Command class for passing messages from client to server, and maybe a separate Response class for sending data from server to client.

...resulting in a doubling in the number of classes. Not necessarily doubling. You just need a separate Response class per possible result type, meaning that - at least in theory - you may have multiple commands using the same response class.Blair, If the server does need to initiate a message, my messaging should be generic enough to do this. I was intending to use the same MessagingPort object (sends and receives messages) the client and the server. I think that by coupling server-side commands with client-side ones, your system is not generic at all. When a server initiates a message to the client, it performs a "callback" to the client. As such a callback is not related to any server-side command, it's easier to keep them separate. While most server commands return something to the client, callbacks will typically be void commands. Moreover, if you use callbacks as I do, the server must be able to talk to any client independantly of the current client connection context (initiating a command, or waiting for a result or doing nothing). So I think that you need a separate communication way for callbacks if you want to implement them (the client acting as a server on some callback port). I like your ServerContext context parameter in your performServerTask method. I suppose that your connections are permanent and stateful and that your ServerContext object is what I called Session in my Command interface :

Blair, I wasnt aware of the Value or Transfer Object Pattern in this context, I think its a good idea. The only drawback is that you have these horrible if or switch statements at either end to determine what sort of action it is. With a Command object, one simply needs to call performTask() and doesnt need to interpret it in a switch statement. I agree that such a switch statement is ugly and that you should avoid it. Best, Phil.

blair cairns
Greenhorn

Joined: Oct 24, 2002
Posts: 8

posted Oct 27, 2003 11:40:00

0

Hi, Thank you all for your feedback. Well, I read the specification in a bit more depth and found out that my client needs to implement the methods of the Data class. This is discussed in Should lock methods be callable by the client. This means that I can still send Commands but the answers can't be Commands, because the DataClient method getRecords() needs to return FieldInfo[] and not some command object. So my client side now looks like this:

I have left out some stuff..but you should get the idea. Phil.

I like your ServerContext context parameter in your performServerTask method. I suppose that your connections are permanent and stateful and that your ServerContext object is what I called Session in my Command interface

Not quite, my context is actually a Mediator...it contains a list of sessions as well as references to classes that are often used. I called it context earlier because I didn't know there was a word for it . I'm still thinking about whether it should be a parameter or a singleton. (i am a slow thinker). I think Command objects are ideal for serialized communication its a shame that the spec. prevents me from implementing what I would like. Regards