Observer model
The sample
Wechat public account, follow can receive push messages, cancel the follow will not receive
define
Defines a one-to-many dependency between objects. When one end object changes, all its dependencies are notified and automatically updated (the update method is called). The observer mode is also called: listener mode, publish/subscribe mode. Provides a loose-coupling design between objects interface – oriented programming, registration, callback mechanism
Design principles
Strive for loose coupling design between interacting objects
intentions
Defines a one-to-many dependency between objects. When one end object changes, all its dependencies are notified and updated automatically
Main problem solving
The problem of one object notifying other objects of state changes, with ease of use and low coupling in mind, ensuring a high degree of collaboration
When to use
When an object’s state changes, all dependencies are notified
The advantages and disadvantages
Advantages:
- The observer and the observed are abstractly coupled
- A trigger mechanism can be set up
Disadvantages:
- Notifying all observers takes time if there are many observers
- If there is a cyclic dependency between the observer and the observing target, the observing target will trigger a cyclic call between them, possibly causing the system to crash
- The observer does not know how the object of observation has changed, only that the object of observation has changed, right
Here’s the class diagram:Roles involved:
- Abstract Subject Role: Subject role keep all references to the observer in a gathered (such as the list collection), each theme can have any number of observers, abstract subject provides an interface that can add or remove the observer, the subject role also known as abstract (observables) observed, usually with an abstract class or interface implementation
- The Abstract Observer role: Defines an interface for all concrete observers to update themselves when notified by a topic. This interface is called the update interface. The abstract Observer role is usually implemented by an abstract class or interface
- ConcreteSubject Role: Stores state into a Concrete observer object, notifying all registered observers when the internal state of a specific topic changes. ConcreteSubject role, also called Concrete Observable role, is usually implemented by a subclass
- ConcreteObserver Role: Stores state that is consistent with the state of the topic, implementing the update interface required by the abstract observer role to harmonize its state with the state of the topic, usually implemented by a subclass
Subject:
public interface Subject {
/** Add a new observer */
void attach(Observer observer);
/** Removes a registered observer */
void detach(Observer observer);
/** Notify all registered observers */
void notifyObservers(a);
}
Copy the code
ConcreteSubject class:
public class ConcreteSubject implements Subject {
private List<Observer> list = new ArrayList<>();
@Override
public void attach(Observer observer) {
list.add(observer);
}
@Override
public void detach(Observer observer) {
list.remove(observer);
}
@Override
public void notifyObservers(a) {
for(Observer o : list) { o.update(); }}}Copy the code
The Observer:
public interface Observer {
/** The observer updates itself */
void update(a);
}
Copy the code
ConcreteObserver class:
public class ConcreteObserver implements Observer {
@Override
public void update(a) {
System.out.println("I am notified"); }}Copy the code
The story of the goddess and her pursuer
The goddess Cuihua is a flower in the village. There are many people pursuing it, such as Lao Wang who lives next door, Xiaoming who grew up together from childhood, and Tony teacher from the village barber shop. They are cuihua’s wechat friends and always pay attention to the dynamics of Cuihua. An example of an Observable class is as follows:
public interface Observable {
/** Add observer */
void addObserver(Observer observer);
/** Remove observer */
void removeObserver(Observer observer);
/** Notify all observers */
void notifyAllObservers(a);
}
Copy the code
Goddess Cuihua’s circle of friends:
public class GoddessPyq implements Observable {
private List<Observer> list = new ArrayList<>();
private String msg;
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void removeObserver(Observer observer) {
list.remove(observer);
}
public void pushMsg(String msg) {
this.msg = msg;
System.out.println("Post it on Moments:" + msg);
notifyAllObservers();
}
@Override
public void notifyAllObservers(a) {
for(Observer o : list) { o.update(msg); }}}Copy the code
The Observer:
public interface Observer {
/ * * update * /
void update(Object object);
}
Copy the code
Lao Wang, Xiao Ming, Tony’s circle of friends: always pay attention to whether Cuihua hair circle of friends
public class LaoWang implements Observer {
@Override
public void update(Object object) {
System.out.println("LaoWang- Goddess next door:"+ object); }}Copy the code
public class XiaoMing implements Observer {
@Override
public void update(Object object) {
System.out.println("XiaoMing- My dear goddess:"+ object); }}Copy the code
public class Tony implements Observer {
@Override
public void update(Object object) {
System.out.println("Tony- beauty of frequent visitor:"+ object); }}Copy the code
Test class: goddess posted a circle of friends, Lao Wang, Xiao Ming, Tony can receive notification
public class Test {
public static void main(String[] args) {
GoddessPyq pyq = new GoddessPyq();
pyq.addObserver(new LaoWang());
pyq.addObserver(new Tony());
pyq.addObserver(new XiaoMing());
pyq.pushMsg("I was late for work today. I really want a ride.");
System.out.println();
pyq.pushMsg("Fancy a purse, but no money.");
System.out.println();
pyq.pushMsg("The computer broke down today."); }}Copy the code
Class diagram:
Implementation in Java
Java provides a common implementation of the Observer pattern: java.util. Observable, which extends the java.util.Observer interface
public class JDKObserverSample {
public static void main(String[] args) {
Observable subject1 = new Observable() {
public synchronized void notifyObservers(Object data) {
setChanged();
super.notifyObservers(data); }}; subject1.addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("Observer 1 has been notified that it has been updated..."+ arg); }}); subject1.addObserver(new Observer() {
@Override
public void update(Observable o, Object arg) {
System.out.println("Observer 2 has been notified that it has been updated..."+ arg); }}); subject1.notifyObservers("change1");
subject1.notifyObservers("change2"); }}Copy the code
Observable is a class that doesn’t implement an interface, so the theme must inherit from it, which can be a problem if the theme wants to inherit from another class. Limit its reuse potential