Observer model
Define a one-to-many dependency between objects where a state change in one object results in all its dependents being notified and updated automatically.
Literally, define one-to-many dependencies between objects, with all dependencies automatically notified and updated when an object’s state changes. Publish/subscribe, event notification, data source/listener, etc.
Observer model UML
UML classes and sequence diagrams
Class diagram: The Subject class does not directly update the state of dependent objects. Instead, the Subject references the observer interface for updating state (update()), which makes the Subject independent of how the dependent object updates its state. The Observer1 and Observer2 classes implement the Observer interface by synchronizing state with the state of the Subject.
Sequence diagrams: Observer1 and Observer2 objects register themselves by calling Attach (this) on Subject1. If the state of Subject1 changes, Subject1 itself calls notify(). Notify () calls Update () on registered Observer1 and Observer2 objects, which requests the changed data (getState()) from Subject1 to update(synchronize) its state.
UML class diagrams
Observer mode role
Subject: A target, also known as a Subject, is an object being observed. An observation target can accept any number of observers to observe. It provides a series of methods to add and remove observer objects. It also defines the notify method (). The target class can be an interface, an abstract class or a concrete class.
ConcreteSubject: A concrete target is a subclass of the target class. It usually contains frequently changing data and notifies its observers when its state changes. It also implements the abstract business logic methods (if any) defined in the target class. If the target class is not extended, the concrete target class can be omitted.
Observer: An Observer reacts to changes in the object of observation. An Observer is generally defined as an interface that declares the method update() for updating data. Therefore, it is called an abstract Observer.
ConcreteObserver: In the ConcreteObserver, a reference to the ConcreteObserver is maintained. It stores the ConcreteObserver states that correspond to the ConcreteObserver states. It implements the update() method defined in the abstract Observer Observer.
The Observer pattern describes how to establish object-to-object dependencies and how to construct systems that meet these requirements. The observer mode includes two types of objects: the observation target and the observer. A target can have any number of dependent observers. Once the state of the observation target changes, all the observers will be notified. In response to this notification, each observer monitors the state of the observed target to synchronize its state with the state of the target, an interaction also known as publish-subscribe. The observation target is the publisher of the notification. It does not need to know who its observers are when it sends the notification. Any number of observers can subscribe to it and receive the notification.
Dry goods source code analysis
The source address
Blog subscriptions feature that maintains subscriptions in abstract topics while introducing regular and VIP observers.
// Abstract theme
@Data
public abstract class Subject {
// Theme subscribers
private List<Observer> observerList = Lists.newArrayList();
/ / subscribe
public void register(Observer observer) {
observerList.add(observer);
}
// Unsubscribe
public void remove(Observer observer) {
observerList.remove(observer);
}
// Publish things
public abstract void publish(String msg);
}
// Abstract the observer
@Slf4j
@Data
@AllArgsConstructor
public abstract class Observer {
// Observer name
private String name;
// Update status, scheduled by topic
public void update(Object subject, Object args) {
log.info("{} received change notification: {}", name, args); }}// Blog theme
@Slf4j
public class Blog extends Subject {
@Override
public void publish(String msg) {
log.info("Release MSG: {}", msg);
// Notify subscribers
getObserverList().forEach(observer -> observer.update(this, msg)); }}// Ordinary user observer
@Slf4j
public class NormalObserver extends Observer {
public NormalObserver(String name) {
super(name);
}
@Override
public void update(Object subject, Object args) {
super.update(subject, args);
log.info({} get change notification: normal user can not cache", getName()); }}// VIP user observer
@Slf4j
public class VipObserver extends Observer {
public VipObserver(String name) {
super(name);
}
@Override
public void update(Object subject, Object args) {
super.update(subject, args);
log.info({} get change notification: VIP can be cached, getName()); }}@Slf4j
public class Application {
public static void main(String[] args) {
Blog blog = new Blog();
VipObserver wang = new VipObserver("Lao wang, 99");
VipObserver lee = new VipObserver("老李");
NormalObserver four = new NormalObserver("Small four.");
NormalObserver twoEgg = new NormalObserver("The egg");
log.info("---------------------begin--------------------");
// Users subscribe to blogs, regular and VIP users
new Thread(() -> {
blog.register(wang);
sleep(2);
blog.register(lee);
sleep(2);
blog.register(four);
}).start();
// The blog thread posts every 2 seconds for a total of 4 posts
new Thread(() -> {
IntStream.rangeClosed(1.4).forEach(i -> {
blog.publish(String.format("New trick %s", i));
sleep(2);
});
}).start();
// Some users quit the blog and some users join the blog
new Thread(() -> {
sleep(3);
blog.remove(lee);
sleep(2);
blog.register(twoEgg);
}).start();
}
private static void sleep(int seconds) {
try {
TimeUnit.SECONDS.sleep(seconds);
} catch (InterruptedException e) {
log.error("error : ", e); }}}Copy the code
JDK built-in Obverser and Observable
@Slf4j
public class ObserverApplication {
public static void main(String[] args) {
log.info("Enter Text: ");
EventSource eventSource = new EventSource();
eventSource.addObserver((obj, arg) -> {
log.info("Received response: {}", arg);
});
eventSource.addObserver((obj, arg) -> {
log.info("Received response2: {},,{}", arg, obj
);
});
newThread(eventSource).start(); }}class EventSource extends Observable implements Runnable {
public void run(a) {
while (true) {
String response = newScanner(System.in).next(); setChanged(); notifyObservers(response); }}}Copy the code
Use in Java
It gives an object the flexibility to send messages to interested objects
java.util.EventListener
javax.servlet.http.HttpSessionBindingListener
javax.servlet.http.HttpSessionAttributeListener
javax.faces.event.PhaseListener
A Listener b Listener C Listener D Listener
Obverser and Observable built into the JDK
Built-in observer mode in the JDK. Observer(interface) and Java.util. Observable(class).
Just a quick word about that. Observer interface (java.util.observer), theme (java.util.Observable). Implement the observer interface and inherit topics. The observer is registered via addObserver() of the abstract topic and removed via deleteObserver().
First, notifyObservers of state changes by calling setChange() of the subject class, then notifyObservers of these changes with notifyObservers, and finally, because the subject is astute about notifyObservers update(), which has two parameters, The first is a topic object, and the second is a mutable parameter.
conclusion
The Observer pattern is a very frequently used design pattern and is implemented in the JDK. No matter it is mobile application, Web application or desktop application, the observer mode is almost everywhere. It provides a complete solution for realizing the linkage between objects, and it can be used in one-to-one or one-to-many object interaction scenarios. The Observer pattern is widely used in the implementation of GUI event processing in various programming languages, as well as in event-based XML parsing technologies such as SAX2 and In Web event processing.
Advantages of the observer model
(1) Observer mode can realize the separation of presentation layer and data logic layer, define a stable message update transmission mechanism, and abstract the update interface, so that a variety of different presentation layer can act as a specific observer. (2) The observer mode establishes an abstract coupling between the observation target and the observer. The object of observation only needs to maintain a collection of abstract observers, without knowing its specific observers. Since the object and observer are not tightly coupled, they can belong to different levels of abstraction. (3) The observer mode supports broadcast communication, and the observation target will send notification to all registered observer objects, simplifying the difficulty of one-to-many system design. (4) The observer mode meets the requirements of the “open and closed principle”, and it is not necessary to modify the original system code to add new specific observers. It is also convenient to add new observation targets when there is no correlation between specific observers and observation targets.
Disadvantages of the observer model
(1) If an observation object has many direct and indirect observers, it will take a long time to notify all observers. (2) If there is cyclic dependence between the observer and the observation target, the observation target will trigger cyclic calls between them, which may lead to system crash. (3) The observer mode has no corresponding mechanism to let the observer know how the observed object changes, but only know that the observed object changes.
Matters needing attention
JAVA already has classes that support the Observer pattern. 2. Avoid circular references. 3. If executed sequentially, an observer error will cause the system to jam, usually asynchronously.
reference
Observer pattern
The observer pattern | novice tutorial
Count the design patterns in the JDK
Design Pattern Summary (Java) – Observer pattern
Welcome to attention