Distribution is an important aspect of architecture. An architecture identify the components of a system and relations between them, so distribution indicate components (in general sense) that exist in multiple address space (e.g..: components of a system distribuited on a network). There are two kind of distribution Symmetric and Asymmetric. Asymmetric distribution means that the relations between distribuited object is known at design time. Symmetric, instead, means that the relation are known at run time (one object don’t know where another object is located until run-time). There are many distribuited patterns (see POSA series book) but I’ll focused on (for this first post) Observer Pattern, broker pattern and Proxy pattern.
The observer pattern enable a set of clients to be nototified (push model) from an event by server. This type of communication is very efficient because reduce the “data spam” between client and server, the server sends only information that one client need (have registrated to). Formally it’s not a distribution pattern but It’s used as basis for other one. There are many advantages using this pattern, first decoupling publisher from subsciber. Second, runt-time management of clients. One client can choose to receive some data (and then register on server) in a specified moment or choose to no; all this at run-time. 3rd, the policy about notification towards clients is centralized on server and this make simpler every modification.
The implementation strategies in all object oriented languages is enough common, the client invoke the subscribe passing a reference or pointer (of a queue, for example) to a server that keep it for future notify. The client can even invoke the unsubscribe that enable the server to remove the entry. In not OO languages (like C) it’s done with pointer or callback mechanism. In the callback mechanism the server call a function of the client that manage the received data (be carefull at race condition !).
The notification (the server invoke notify() function that pass data to all client registered) can occur, basically, in three way :
- when the data is changed and then the server notify all registered client. When the data is changed means that exist an in memory db to verify that
- As soon as the data are received
Observer pattern, in all literature, is saw as pattern that implement the publish-subscriber mechanism in the context of the same address space (e.g.: the same process).
If our requirement need to enable the communication among objects (one server and one or more clients) in different address space (e.g.: different process located on a network) then can help us two other pattern : Broker and Proxy pattern. I want write about this patterns because both are an example of extension of observer pattern and are an example of asymmetric (Proxy) and symmetric (broker) kind of communication.
The proxy is an asymmetric pattern that decouple server from client located in different address space. This means that I can have a server on a machine, a client on another machine that “know” the server at design-time (e.g.: the ip address in a configuration file). The primary reason to use a proxy pattern is to hide the server details to client. Even more today systems are deployed on different processor and this means that if we hard code the IP of a server on a client at every deploy we have to change our system, moreover an intimate awareness of server detail on clients make difficult every client porting to new platform. The main constraint of this pattern is that the client have to know the server before run-time (this constraint is removed from broker pattern, as we’ll see). It works, more or less, in this mode : The AbstractProxy class provides a common features to manage the client subscription/unsubscription and server notification service. ClienSideProxy (specialization of AbstractProxy) represent the server proxy (stand-in) on client side application. The ServerSideProxy (specialization of AbstractProxy) is the server proxy by server side. For every proxy server side there are one or more client proxy (and so client). This should clarify that a client communicate with the server is done by means the proxy (client and server proxy). Abstract client and Abstract server represent the abstraction of client and server (business class). Notification handle (local and remote notification handle) is necessary for client proxy and server proxy to keep track of all subscriber (all clien proxy for server proxy, all client for client proxy respectively). The sequence is : There is a subscription/unsubscription on two layer. First concreteclient(s) subscribe to clientsideProxy, two clientSideProxy subscribe serversideProxy (here is necessary the local and remote notification handle). At this point when concreteServer needs call send() method on serverSide proxy that walk their notification list (there are one or more clientSideProxy subscribed) and send the message. The clientSideProxy when receive the message in turn walk their notification list (there are one or more concrete clients subscribed) to send the data to all local notification list.
As said the main limitation is that the concreteClients have to know concreteServer at design time, but (often) in real-time systems it’s an advantages because do not add latency in finding services around the network (for example).
For Broker pattern is valid almost all said for proxy pattern exept that this is a symmetric pattern (clients do not know where the server is) and this means that the client will locate the server at run-time. In order to do this we need to add a Broker object repository to preview (proxy) class diagram. The logic is more or less the same. Concrete server (through serverSideProxy) use the broker to publish their service and ConcreteClient request the service direct to the broker or (second option) request server address and comminicate directly with it. The broker pattern is the core of CORBA (Common Object Request Broker Architecture).
The increasing complexity of systems does not allow us to design a bad solution because a few hours saved today means trouble tomorrow for mantaining this system, difficult to debug and diffcult to undestand.