The Observer pattern implementation structure from the Java language, diagrammed in Figure 11-1, is richer than you need for the pattern definition. Further, the Observable class implementation needs to be an interface definition for use in the Web Service paradigm. You will use a structure that is more akin to the original Observer structure presented in the Gang of Four (GoF) design pattern book. These changes are enough to redraw Figure 11-1 with the updated structure, shown in Figure 11-2.
Using the interface for the Observable implementation gives you more flexibility for the ConcreteObservable itself. Figure 11-2 also shows a better representation of the relationship between ConcreteObservable and Observer . This relationship is 0 or more on both the client and the supplier cardinality. An Observer can service multiple Observable relationships, as long as the logic in the Observer can tell the difference between the targets with which it registers.
The Observer pattern contains two critical interface definitions: Observer and Observable . In addition, two concrete Web Service implementations perform the collaborations. The components are as follows :
Observable: This is the interface to a Web Service that contains data of interest to others. For example, business processes typically have the process status associated with them. As processes change state, perhaps from packaging to shipping, clients will want notification to update their own data and, perhaps, a user of the receiving application. There are two primary operations, an addObserver and a removeObserver operation. The addObserver method, which takes a single parameter of the location of the particular Observer implementation, adds a particular concrete observer to the list of observers to notify when a state change occurs. The removeObserver operation removes a particular Observer from the list of observers to notify. Identification of an observer's location can occur in a variety of ways. You can use a string with the binding information or a more robust identifier such as a tModel or a WSDL file that contains binding information.
ConcreteObservable: The concrete implementation of the Observable interface bears the responsibility for maintaining a list of Observers interested in state changes. The service implementation maintains a list of the target clients and delivers the notifications to the target Observer .
Observer: The Observer is the definition of the interface that the concrete observable implementation calls to notify a client of a change to a business entity, collection, or process. There is only a single important operation on this method: the update operation. The Observable implementation calls this operation for change notification.
ConcreteObserver: The concrete observer adheres to the Observer interface. Upon changing state, the concrete observable delivers a message to each concrete observer registered in its list of interested parties. ConcreteObservable requires the address of ConcreteObserver , typically a Uniform Resource Locator (URL), in order to bind to ConcreteObserver . The ConcreteObserver implementation then acts on the update.
The collaborations in the Observer pattern occur between the concrete implementations, the ConcreteObservable and the ConcreteObserver . The collaborations between Observer and Observable are relatively straightforward and follow those collaborations of the original Observer pattern (see Figure 11-3).
A client creates a concrete observer. Upon creation, the concrete observer registers with the concrete observable via the addObserver method, or a separate client could register the concrete observable. Recall that the parameter of the addObserver method identifies the location that the observable uses to communicate with the observer. When an observable determines it is time to notify observers of changes, it calls the update operation on each registered observer.