From: Karsten Wutzke on
Hello all!

Be warned, this is a practical question... ;-)

Some time ago I've had some discussions about the Proxy pattern to
apply to implementing the client side of a chat application.

After I decided upon a solution, I felt the Proxy pattern is a
somewhat strange pattern. I never really grasped the purpose of a
remote chat (channel) proxy. Basically it is just a stupid object from
some subclass representing what is stored and happening on a chat
server.

From an abstract point of view one or more instances are needed to
basically accomplish two things:

1. Receive messages from the server and translate those into an MVC
style model object which needs to update itself and notify the GUI
appropriately. This would serve as an *incoming* messages interface.

2. From the GUI itself, the locally logged in user can issue commands
of some kind, e.g. "join chat", "send message", "kick user", "create
new chat" etc. This is the *outgoing* messages component.

What I did was to create a simple chat interface modeling one command
per method (interface Chat):

public boolean join(User usr); //add
public boolean part(User usr); //remove
public boolean send(User usrSender, String strMessage);
public boolean kick(User usrKicker, User[] usrKickeds);
...

The chat server class with the thread waiting for messages to arrive
(class ChatServer implements Runnable) parses the message and sets the
chat model's properties ("send message" on a model class). The model
class extends some Observable class (class ChatModel extends
Observable implements Chat), which is somewhat typical for model
objects (incoming part). I created another chat class (class ChatProxy
implements Chat) for the outgoing part. Both incoming model interface
and outgoing proxy interface share the same interface. The getter
methods simply delegate to the model object so that the very latest
actual model properties can be retrieved.



----------------- * 1
-----------------
| Chat |<----------------------| ChatServer
|
-----------------
-----------------
^
|
------------+------------
| |
----------------- -----------------
| ChatModel |<------| ChatProxy |
----------------- -----------------

I'm very unsure if I understood the proxy pattern right here...
creating the model class seemed perfect as I do so in every program.
The proxy (as interpreted by myself above) delegates all getters to
the model and only has outgoing implementations differing from the
model. The implementation of kickUser on the model actually tries to
find the user in the chat's user list and removes that user if found,
the implementation of kickUser on the proxy class generates a server
message and puts some server specific byte stream on a socket.

As I said, I'm unsure about the implementation, it seems quite
complicated. I could as well merge the two subclasses and create two
different sets of methods in that class, one that basically handles
incoming messages like "removeUser" after a kick and one method
kickUser that obviously generates an outgoing message...

I guess both approaches basically work, I just can't figure out why I
really chose the former. I'd like to get some input on what is the
better approach and why. Maybe there's a third or fourth, anway I'd
like to get some opinions on that.

TIA
Karsten

PS: The exmples above are Java centric
From: H. S. Lahman on
Responding to Wutzke...

> From an abstract point of view one or more instances are needed to
> basically accomplish two things:
>
> 1. Receive messages from the server and translate those into an MVC
> style model object which needs to update itself and notify the GUI
> appropriately. This would serve as an *incoming* messages interface.
>
> 2. From the GUI itself, the locally logged in user can issue commands
> of some kind, e.g. "join chat", "send message", "kick user", "create
> new chat" etc. This is the *outgoing* messages component.
>
> What I did was to create a simple chat interface modeling one command
> per method (interface Chat):
>
> public boolean join(User usr); //add
> public boolean part(User usr); //remove
> public boolean send(User usrSender, String strMessage);
> public boolean kick(User usrKicker, User[] usrKickeds);
> ...
>
> The chat server class with the thread waiting for messages to arrive
> (class ChatServer implements Runnable) parses the message and sets the
> chat model's properties ("send message" on a model class). The model
> class extends some Observable class (class ChatModel extends
> Observable implements Chat), which is somewhat typical for model
> objects (incoming part). I created another chat class (class ChatProxy
> implements Chat) for the outgoing part. Both incoming model interface
> and outgoing proxy interface share the same interface. The getter
> methods simply delegate to the model object so that the very latest
> actual model properties can be retrieved.

Does either the GUI or the chat server care about different threads in
the client for managing different chats simultaneously? No. That's why a
proxy comes in handy. It hides such details from the clients -- in both
directions. It probably also acts as a kind of Observer for the GUI that
converts server chat identity into GUI identity (i.e., it knows how to
convert server messages into chat window handles or something else the
GUI layer cares about).

My pushback is twofold. It seems to me that the thing requiring a proxy
is the server rather than the chat. That's where you need to make
identity and thread mapping decisions. In that case the proxy would be
two-way as it addressed messages properly to both MVC model instances
and the server(s).

I would see the MVC object as a dumb data holder that was basically a
pass-through for messages to/from the GUI. (There would be a 1:1
correspondence between GUI chat window instances and MVC Chat
instances.) IOW, the GUI object has the rendering smarts for draw()
while the server proxy has the smarts for keeping track of who is
talking to whom and ensuring they don't step on one another.

BTW, in the Proxy pattern note that the client is always talking to the
proxy instance. The proxy subclass instance then talks to the actual
subject instance. This allows the proxy to insert additional <hidden>
housekeeping behaviors into the responsibility that the client thinks it
is invoking.

To that extent the GoF structure representation is misleading because it
implies that the Client could be related directly to a RealSubject
instance. That's possible if there are other, unaugmented RealSubject
responsibilities that could be accessed directly by the client. However,
it would require a lot of care because one would have to ensure that
when the augmented responsibilities were needed the relationship is not
instantiated to a RealSubject. So in practice the relationship between
Client and Subject is almost always instantiated only at the Proxy
subclass level rather then the Subject superclass.



--
There is nothing wrong with me that could
not be cured by a capful of Drano.

H. S. Lahman
hsl(a)pathfindermda.com
Pathfinder Solutions
http://www.pathfindermda.com
blog: http://pathfinderpeople.blogs.com/hslahman
"Model-Based Translation: The Next Step in Agile Development". Email
info(a)pathfindermda.com for your copy.
Pathfinder is hiring:
http://www.pathfindermda.com/about_us/careers_pos3.php.
(888)OOA-PATH