Design Pattern-Observer pattern (Observer)
To understand the design pattern correctly, we must first clarify what problems it proposes to solve.
Design Mode Study Notes, welcome to exchange.
1. Concepts
The observer mode is the behavior mode of objects. There are many outer numbers ...!! It is also called the Publish/Subscribe mode, Model-View Mode, Source-Listener mode, or Dependents mode.
The observer mode defines a one-to-many dependency, allowing multiple observer objects to listen to a topic object at the same time. When the status of this topic object changes, it notifies all observer objects so that they can automatically update themselves.
2. Problems
When the status of the observed object changes, it notifies all the observer objects so that they can automatically update themselves. Ensure overall data consistency. This mode is usually used to implement the event processing system.
Applicability:
1) When an abstract model has two aspects, one of which depends on the other. Encapsulate the two in independent pairs so that they can be changed and reused independently.
2) When changing an object, you need to change other objects at the same time without knowing how many objects need to be changed.
3) when an object must notify other objects, it cannot assume who the other objects are.
3. role composition
Ø abstract topic role:
Abstract topic roles store all references to observer objects in a aggregation (such as an ArrayList object). Each topic can have any number of observers. Abstract topic provides an interface to add and delete observer objects. Abstract topic roles are also called abstract observer roles.
Ø specific topic (ConcreteSubject) roles:
Stores the status in a specific observer object. When the internal status of a specific subject changes, a notification is sent to all registered observers. A topic role is also called a Concrete Observable role.
Abstract Observer role:
Define an interface for all the specific observers to update themselves when they receive notifications of the topic. This interface is called the update interface.
Ø specific observer role:
The storage status is the same as that of the topic. The specific observer role implements the update interface required by the abstract observer role to coordinate its status with the status of the topic. If necessary, a specific observer role can maintain a reference pointing to a specific topic object.
4. Examples
4.1 example description
The instance simulates the water burning process, involving three objects: Heater (water Heater), Display (Display), and Alarm (Alarm ). Simulation process: For easy operation, the initial temperature of the water is 90, the boiling point is 100, the display according to the water heater display temperature, the display temperature is 100, the alarm starts. Obviously, it can be seen that Heater is subject, Display is its Obsrver, and Display is also subject, because it is to be observed by the Alarm, so Alarm is the Observer of Display.
4.2 class diagram
(PS: if you do not know the meaning of various symbols, see here -- http://blog.csdn.net/zhshulin/article/details/18088633)
4.3 Source Code
Subject: Abstract observer
Package org. zsl. designmodel. observer; import java. util. arrayList; import java. util. list;/*** observer role * @ author ZSL **/public abstract class Subject {private List
List = new ArrayList
();/*** Register the observer object * @ param Observer observer */public void registerObserver (observer Observer) {list. add (observer); System. out. println (registered an observer role !);} /*** Delete the observer object * @ param Observer observer */public void removeObserver (observer Observer) {list. remove (observer);}/*** notifies all registered observer objects. My status changes slightly * @ param newState */public void policyallobservers (String newState) {for (Observer observer: list) {observer. update (newState );}}}
Observer: Observer interface, with only one update () method
Package org. zsl. designmodel. observer; /*** Observer interface ** @ author ZSL **/public interface Observer {/*** update interface ** @ param state update status */public void update (String state );}
Heater: water Heater, a specific observer
Package org. zsl. designmodel. observer; public class Heater extends Subject {private int temperature; public int getTemperature () {return temperature;} public void setTemperature (int temperature) {this. temperature = temperature;} public void boilWater () {for (int I = 95; I <105; I ++) {temperature = I; this. setTemperature (temperature); // set the new temperature this. notifyAllObservers (Integer. toString (temperature); // notify all registered observers }}}
Display: both the observer and the observer
Package org. zsl. designmodel. observer;/*** Display, both the Observer and the observer * @ author Administrator **/public class Display extends Subject implements Observer {private boolean isBoiled = false; // indicates whether the private int displayTemperature is enabled; // defines the display temperature public boolean isBoiled () {return isBoiled;} public void setBoiled (boolean isBoiled) {this. isBoiled = isBoiled;} @ Overridepublic void update (String state) {displayTemperature = Integer. parseInt (state); System. out. println (the current display temperature is: + displayTemperature); this. displayTemperature (displayTemperature);} private void displayTemperature (int temperature) {if (temperature> 100) {this. setBoiled (true); this. notifyAllObservers (Boolean. toString (isBoiled ));}}}
Alerm: only the observer
Package org. zsl. designmodel. observer; public class Alarm implements Observer {private String observerState; // defines the observer state @ Overridepublic void update (String state) {Boolean flag = Boolean. parseBoolean (state); if (flag) {System. out. println (the alarm goes off and the water temperature exceeds 100 degrees .);}}}
Test
package org.zsl.designmodel.observer;public class Test {public static void main(String[] args) {Heater heater = new Heater();Display display = new Display();Alarm alarm = new Alarm();heater.registerObserver(display);display.registerObserver(alarm);heater.boilWater();}}
Result:
5. Advantages
A. Support for loose coupling and dependency reduction
The client no longer depends on the Observer, because the client is isolated by using the subject and Observer interfaces. Many frameworks have this advantage, and application components in these frameworks can be registered as notified when (low-level) Framework events are generated. As a result, the Framework calls the application component but does not depend on it.
B. improves the maintainability and reusability of applications
One principle of object-oriented design is that every class in the system focuses on a certain function, rather than other aspects. An object only does one thing and completes it. The observer mode clearly defines the boundaries between modules, improving the maintainability and reusability of applications.
C. variable number of observers
The observer can be attached and detached at runtime, because the subject has no assumptions about the number of observer. This function is useful in the following situations: the number of inspector is unknown during design. For example, if you need an observer for each window opened in an application.
6. Disadvantages
A. reduced performance.
In many implementations, the update () method of the observer may be executed in the same thread as the subject. If the observer list is long, it may take a long time to execute the Notify () method. The dependency of the extracted object does not mean that adding the observer has no impact on the application.
B. Memory leakage.
The callback mechanism used in The Observer (when the object is registered for future calls) will generate a common error, resulting in Memory leakage, or even in the hosted C # code. Assuming that the observer is out of scope, but the user forgets to cancel the subscription to the subject, the subject still retains the reference to the observer. This reference prevents spam from allocating the memory associated with the observer before the subject object is damaged. If the lifetime of the observer is much shorter than the lifetime of the subject (usually this case), it will cause serious memory leakage.
C. Hidden dependencies.
The use of the observer converts explicit dependencies (called by method) to implicit dependencies (through the observer ). If the observer is widely used throughout the application, it is almost impossible for developers to view the source code to understand what is going on. In this way, it is very difficult to understand the meaning of code changes. This problem increases dramatically with the propagation level (for example, serving as a Subject observer ). Therefore, the observer should be used only in a few well-defined interactions (for example, interactions between models and views in Model-View-Controller mode. It is best not to use an observer between domain objects.
D. Difficult to test/debug.
Although loose coupling is a major architectural feature, it can make development more difficult. The more decoupling two objects, the more difficult it is to understand the dependencies between them when you view the source code or class relationship diagram, only when the association between two objects can be safely ignored should they be loosely coupled (for example, if the observer has no side effects ).