Design Patterns_Behavioral Patterns - "Observer Patterns"

Design Patterns_Behavioral Patterns - "Observer Patterns"

The notes are organized from the detailed explanation of Java design patterns by dark horse programmers, 23 Java design patterns (diagram + framework source code analysis + actual combat)

overview

definition

  • The observer mode, also known as the publish-subscribe (Publish/Subscribe) mode, defines a one-to-many dependency relationship, allowing multiple observer objects to listen to a subject object at the same time. The subject object notifies all observer objects of state changes, enabling them to update themselves automatically.

structure

The Observer Pattern has the following roles:

  • Subject: abstract subject (abstract observed), the abstract subject role saves all observer objects in a collection, each subject can have any number of observers, abstract subject provides an interface, you can add and delete observer objects .
  • ConcreteSubject: Specific subject (specific observer), this role stores the relevant state into the specific observer object, and sends a notification to all registered observers when the internal state of the specific subject changes.
  • Observer: Abstract observer is an abstract class of observer, which defines an update interface, so that it updates itself when it is notified of theme changes.
  • ConcrereObserver: Concrete observer, which implements the update interface defined by the abstract observer, so as to update its own state when it is notified of topic changes.

Case realization

[Example] WeChat official account

When using the WeChat official account, everyone will have such an experience. When there is a new content update in the official account you follow, it will be pushed to the WeChat client who follows the official account. We use the observer mode to simulate such a scenario. The WeChat user is the observer, and the WeChat official account is the observed (subject role). There are multiple WeChat users who follow the official account of Program Ape.

The class diagram is as follows:

code show as below:

  • Abstract observer class, which defines an updated method

    public interface Observer {
          
          
        void update(String message);
    }
    
  • The specific observer class, WeChat users are observers, which implements the update method

    public class WeixinUser implements Observer {
          
          
        // 微信用户名
        private String name;
    
        public WeixinUser(String name) {
          
          
            this.name = name;
        }
        
        @Override
        public void update(String message) {
          
          
            System.out.println(name + "-" + message);
        }
    }
    
  • Abstract subject class (observed), which provides three methods of attach, detach and notify

    public interface Subject {
          
          
        // 增加订阅者(观察者对象)
        public void attach(Observer observer);
    
        // 删除订阅者(观察者对象)
        public void detach(Observer observer);
        
        // 通知订阅者更新消息
        public void notify(String message);
    }
    
  • The WeChat public account is a specific topic class (specifically the observer), which stores the WeChat users who subscribe to the public account, and implements the methods in the abstract topic

    public class SubscriptionSubject implements Subject {
          
          
        // 储存订阅公众号的微信用户
        private List<Observer> weixinUserlist = new ArrayList<Observer>();
    
        @Override
        public void attach(Observer observer) {
          
          
            weixinUserlist.add(observer);
        }
    
        @Override
        public void detach(Observer observer) {
          
          
            weixinUserlist.remove(observer);
        }
    
        @Override
        public void notify(String message) {
          
          
            for (Observer observer : weixinUserlist) {
          
          
                observer.update(message);
            }
        }
    }
    
  • client program

    public class Client {
          
          
        public static void main(String[] args) {
          
          
            // 1.创建公众号对象
            SubscriptionSubject mSubscriptionSubject = new SubscriptionSubject();
            // 2.创建微信用户
            WeiXinUser user1 = new WeiXinUser("孙悟空");
            WeiXinUser user2 = new WeiXinUser("猪悟能");
            WeiXinUser user3 = new WeiXinUser("沙悟净");
            // 3.订阅公众号
            mSubscriptionSubject.attach(user1);
            mSubscriptionSubject.attach(user2);
            mSubscriptionSubject.attach(user3);
            // 4.公众号更新发出消息给订阅的微信用户
            mSubscriptionSubject.notify("传智黑马的专栏更新了");
        }
    }
    

    output

    孙悟空-传智黑马的专栏更新了
    猪悟能-传智黑马的专栏更新了
    沙悟净-传智黑马的专栏更新了
    

Advantages and disadvantages

advantage

  • The coupling relationship between the target and the observer is reduced, and there is an abstract coupling relationship between the two.
  • The observed person sends a notification, and all registered observers will receive the information [Broadcast mechanism can be realized]

shortcoming

  • If there are many observers, it will take time for all observers to receive notifications from the observed
  • If the observer has a circular dependency, the notification sent by the observer will cause the observer to call circularly, which will cause the system to crash

scenes to be used

  • There is a one-to-many relationship between objects, and changes in the state of one object will affect other objects.
  • When an abstract model has two aspects, one of which depends on the other.

Implementation provided in JDK - Observable/Observer

In Java, observer patterns are defined by java.util.Observable(抽象主题角色类)and java.util.Observer(抽象观察角色接口), as long as their subclasses are implemented, observer pattern instances can be written.

Observable class

The Observable class is an abstract target class (observed), which has a Vector collection member variable for storing all observer objects to be notified.

private Vector<Observer> obs;
	
// 在无参构造方法中赋值
public Observable() {
    
    
    obs = new Vector<>();
}

Let's introduce its three most important methods.

  • void addObserver(Observer o)Method: Used to add a new observer object to the collection.

    public synchronized void addObserver(Observer o) {
          
          
        if (o == null)
            throw new NullPointerException();
        // 如果不存在则添加到集合中
        if (!obs.contains(o)) {
          
          
            obs.addElement(o);
        }
    }
    
  • void notifyObservers(Object arg)Method: Call the update method of all observer objects in the collection to notify them of data changes. Usually observers who joined the set later will be notified earlier.

    public void notifyObservers() {
          
          
        notifyObservers(null);
    }
    			||
                \/
                    
    public void notifyObservers(Object arg) {
          
          
        Object[] arrLocal;
    
        synchronized (this) {
          
          
            // 只有changed为true才可以执行到下面的for循环
            if (!changed)
                return;
            // 集合转数组
            arrLocal = obs.toArray();
            // 这个方法会将changed置为false 因为即将进行通知
            clearChanged();
        }
    	// 倒序遍历数组 所以这就是为什么越晚加入集合的观察者越先得到通知
        for (int i = arrLocal.length-1; i>=0; i--)
            // 逐一通知观察者(调用update方法)
            ((Observer)arrLocal[i]).update(this, arg);
    }
    
  • void setChange()Method: It is used to set an internal flag of boolean type, indicating that the target object has changed. notifyObservers() will only notify observers when it is true.

    protected synchronized void setChanged() {
          
          
        changed = true;
    }
    

Observer interface

The Observer interface is an abstract observer that monitors changes in the target object. When the target object changes, the observer is notified and calls the update method to perform corresponding work.

【Example】The police caught a thief

The observer pattern can also be used for the police to catch the thief. The police are the observers, and the thief is the observed. code show as below:

  • The thief is an observer, so it needs to inherit the Observable class

    public class Thief extends Observable {
          
          
    
        private String name;
    
        public Thief(String name) {
          
          
            this.name = name;
        }
        
        public void setName(String name) {
          
          
            this.name = name;
        }
    
        public String getName() {
          
          
            return name;
        }
    
        public void steal() {
          
          
            System.out.println("小偷:我偷东西了,有没有人来抓我!!!");
            super.setChanged(); // changed = true,调用通知的方法 才会执行观察者的update方法
            super.notifyObservers();
        }
    }
    
    
  • The police is an observer, so it needs to implement the Observer interface

    public class Policemen implements Observer {
          
          
    
        private String name;
    
        public Policemen(String name) {
          
          
            this.name = name;
        }
        public void setName(String name) {
          
          
            this.name = name;
        }
    
        public String getName() {
          
          
            return name;
        }
    
        @Override
        public void update(Observable o, Object arg) {
          
          
            System.out.println(this.getName() + "警察:" + ((Thief) o).getName() + ",我已经盯你很久了,你可以保持沉默,但你所说的将成为呈堂证供!!!");
        }
    }
    
  • client code

    public class Client {
          
          
        public static void main(String[] args) {
          
          
            // 创建小偷对象
            Thief t = new Thief("隔壁老王");
            // 创建警察对象
            Policemen p = new Policemen("小李");
            // 让警察盯着小偷(订阅)
            t.addObserver(p);
            // 小偷偷东西(发布)
            t.steal();
        }
    }
    

    output

    小偷:我偷东西了,有没有人来抓我!!!
    小李警察:隔壁老王,我已经盯你很久了,你可以保持沉默,但你所说的将成为呈堂证供!!!
    

Guess you like

Origin blog.csdn.net/weixin_53407527/article/details/128628077