Observer is perfectly separated from the observer and observed object. For example, the user interface can be used as an observer, and the business data is observed by the observer, the user interface observes the change of business data. After discovering the data, it is displayed on the interface. One principle for object-oriented design is: Each class in the system will focus on a certain feature, not other aspects. A object only does one thing and do it well. The observer mode has defined clear boundaries between the modules and improves the maintenanceability and reuse of the application.
The observer model has many implementations, fundamentally, the mode must contain two roles: observers and observed objects. In the examples just now, business data is observed, and the user interface is an observer. The observer and the logic association of "observation" between the observer, when the observer changes, the observer will observe such a change and make a corresponding response. If such a viewing process is used between service data, it is possible to ensure that the interface and data are divided, assuming that the demand of the application changes, and needs to modify the performance of the interface, just re-build a user interface, business data There is no need to change.
"Observe" is not "directly call"
When implementing the observer mode, it should be noted that the interactive relationship between the observer and the observed object cannot reflect the direct call between the class, otherwise it will enable the observer and the observed object to be closely coupled, fundamentally Violation of the principle of object-oriented design. Whether it is the observer "observation" observation object, or the observer will change his own change "notice" observer, it should not be called directly.
Example of realizing the observer mode
Realizing the observer model has a lot of forms, a more intuitive is to use a "registration-notification-revoked registration" form. The three graphs below describe such a process:
1: Observer will register ourselves to the object, and store the observer in a container (Container).
2: A variation has occurred (asKpriceChanged) in the figure, and all registered observes are obtained from the container to notify the observer.
3: The observer told the observer to revoke the observation and the observer removed the observer from the container.
The observer will be registered with the observer's container, and the observer should not ask the observer's specific type, but should use the observer's interface. Such an advantage is that there are other observes in the program, so as long as this observer is also the same interface implementation. An observer can correspond to multiple observes, when the observer changes, he can notify all the observer one by one. Based on the interface, not a specific implementation - this provides greater flexibility for the program.
The following code is an example of using C # implement the observer mode:
// "observer" Interfaces public interface IObserver {void Notify (object anObject);} // "observed object" Interfaces public interface IObservable {void Register (IObserver anObserver); void UnRegister (IObserver anObserver);}
Observers and observed objects are achieved from both interfaces, all of which are defined by these two interfaces, not specific implementations. So the observer and the observed object are not bound together. We can easily change the observer and any part of the observed object without affecting other parts.
The specific observable object is achieved below. The following class is a base class that is observed to achieve all methods that must be observed. We use a HashTable as the observer's container. Code as follows: // All the observed object base class public class ObservableImpl: IObservable {// save the observation target container protected Hashtable _observerContainer = new Hashtable (); // Register the observer public void Register (IObserver anObserver) {_observerContainer.Add (anObserver, anObserver);} // deregistration public void UnRegister (IObserver anObserver) {_observerContainer.Remove (anObserver);} // event notification observer public void NotifyObservers (object anObject) {// enumeration observation vessel Inform the event one by one to give them Foreach (IOBSERVER ANOBSERVER IN _OBSERVERCONTAINER.KEYS) {anobserver.notify;}}}
The above class is not the observed object to be implemented, but all the base classes of the observer, which implements all the functions of all observed objects. This class can be simply defined as Abstract, so that the programmer cannot create its examples. Interfaces and virtual classes that implement this interface maintain both loose coupling between classes, but also make multiple specific implementations can use the same function.
The observer mode is finally implemented, using user interface - business data as an example:
// Business Data (Observed) Public Class Somedata: ObservableImpl {// The data in the observer FLOAT _ASKPRICE; // Change the data of the property public float askPRICE {set {_askprice = value; base.notifyobservers (_ASKPRICE); / / Take the changed message to the observer}}} // User interface (Observer) Public Class Somekindofui: IOBSERVER {public void Notify (Object Anobject) {Console.WriteLine ("The New Ask Price is:" anObject);} } // actually call the process public class mainclass {public static void main () {// Create a viewer and the observer Somekindofui ui = new somekindofui (); somedata data = new somedata (); // In the observed object Registered Observer Data.Register (UI); // Change the data in the observed object, then the observer will notify the observer Data.askprice = 1000f; // Dissing the observer, stop observing the stock.unregister (stockdisplay); }
Better implementation in .NET.
The above form is that we have implemented the observer mode in a basic manner, and we have developed a specific type for the observer model. In the .NET framework, use a proxy and events, you can better implement the observer mode. C # Mediation and event introduction can be seen in this article: Trigger the event in the way in C #, triggered the event, there is a detailed description of the proxy and events, there is a routine, here is not much here. There are also their own implementations in other languages supported by .Net. In an event mode, the class that declares event is the observer. The observer does not need to realize the registration of the observer, and only one event is not issued without any operation. The observer does not need to register himself into the observation object, but to create an instance of a specific agent, bind the agent to a method. Use this way to register or revoke the observer to observe the observation object. Carefully study agents and event patterns are not difficult to find that IOBSERVER and IOBSERVABLE interfaces can reduce the coupling between observer and observation objects, and agent and events have almost eliminate coupling between the two modules, flexibility improvement a lot of.
references
Explore observer design patterns Doug Purdy (Microsoft Corporation) Jeffrey Richter (Wintellect)