Proxy Pattern
Starting Point Analysis
Our last prototype in command pattern fulfill all the requirement except that we should change the sigle-user, nondistributed spreadsheet into a multi-user one. In our risk analysis, we already find a technique to solve it. This technique is, in essence, a proxy pattern. In our case, a spreadsheet proxy object is created by Pyro.
Requirement in this phase
Change the single-user, nondistributed spreadsheet to a multi-user, distributed spreadsheet by using proxy patten.
Proxy Pattern Overview
The following simple description of proxy pattern is from the book, Design Patterns. Please see page 207-217 of this book for more details.
Intent
Provide a surrogate or placeholder for another object to control access to it.
Structure
Here's a possible object diagram of a proxy structure at run-time:
Participants
- Proxy (ImageProxy)
- maintains a reference that lets the proxy access the real subject. Proxy may refer to a Subject if the RealSubject and Subject interfaces are the same.
- provides an interface identical to Subject's so that a proxy can by substituted for the real subject.
- controls access to the real subject and may be responsible for creating and deleting it.
- other responsibilities depend on the kind of proxy:
- remote proxies are responsible for encoding a request and its arguments and for sending the encoded request to the real subject in a different address space.
- virtual proxies may cache additional information about the real subject so that they can postpone accessing it. For example, the ImageProxy from the Motivation caches the real image's extent.
- protection proxies check that the caller has the access permissions required to perform a request.
- Subject (Graphic)
- defines the common interface for RealSubject and Proxy so that a Proxy can be used anywhere a RealSubject is expected.
- RealSubject (Image)
- defines the real object that the proxy represents.
UML Design in this phase
The left side of the dash line is the client, the right side of the dash line is the server. We use Pyro to let a spreadsheetsubjectproxy object communicate with the spreadsheetsubject object, we do not care how they talk to each other.
Steps in this phase
- step 1: Ideally, our implementation should following the above UML class design. But as I discussed in the risk analysis, it is not easy to register each observer in the Pyro. So we use socket communication when pyro talks to one observer. So the function of the ObserverProxy is to maintain a connect between the spreadsheetsubject object and an observer object. Since our final version should be in multi-user style, so the cooperation between the users or clients. The spreasheetsubject object also need a way to communicate with the txtinterface object. To simplify the communication, we keep one connection between the server (the remote spreadsheetsubject object) and a client (a txtinterface object). When client get the update notice from the server, it will notify all the observers of this client to update. The following class digram is the one that I implemented.
- step 2: There may be multiple use at the same time. To edit the spreadsheet, any user has to get a token before he/she can do that. But at any time, the server has only one token, which means if a client have gotten a token, all the other users have to wait until the first user return the token. The policy to get a token is FIFS (First In, First Serve). If a user did not get a token, his/her editing for spreadsheet should be ignored.
After this phase, we have the prototype 9. To run this program, when do the following steps:
- %ns (see risk analysis for installation of pyro )
- change directory to ./server, issue the command: %python spreadsheetsubjectserver.py
- log onto another machine or go to a different xterm, change directory to ./client, issue the command: %python client.py. You can repeat doing this step.