zoukankan      html  css  js  c++  java
  • 【设计模式】9.观察者模式

    观察者模式

      观察者(Observer)模式,又叫发布/订阅(Publish/Subscribe)模式。定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够更新自己。适用于当一个对象的改变需要同时改变其他对象时情形。

    结构图:

    Subject:主题(抽象通知者)保存多个观察者,可增加和删除观察者。

    Observer:抽象观察者,得到主题(抽象通知者)的通知时更新自己,提供更新接口

    ConcreteSubject:具体主题(具体通知者),具体主题内部改变时,通知所有注册过的观察者。

    ConcreteObserver:具体观察者,实现更新接口,接收具体主题(具体通知者)的通知。

    其中主题不知道谁是观察者,每个观察者也不知道有其他观察者的存在。

    例:

    public abstract class Subject {
        private List<Observer> list = new ArrayList<>();   // 保存观察者
    
        public boolean add(Observer observer){  // 增加观察者
            if (observer != null) {
                list.add(observer);
                return true;
            }
            return false;
        }
    
        public boolean remove(Observer observer){  // 移除观察者
            if (observer != null) {
                list.remove(observer);
                return true;
            }
            return false;
        }
    
        public void notifyObservers(){           // 通知所有观察者
            for (Observer observer : list) {
                observer.update();
            }
        }
    }
    public class ConcreteSubject extends Subject {
        private String subject_state;     // 主题自身状态
    
        public String getSubject_state() {
            return subject_state;
        }
    
        public void setSubject_state(String subject_state) {
            this.subject_state = subject_state;
        }
    }
    public abstract class Observer {
        public abstract void update();  // 更新状态的接口
    }
    public class ConcreteObserver extends Observer{
        private String name;
        private String observer_state;    // 观察者的状态
        private ConcreteSubject subject;  // 观察的主题(对象)
    
        public ConcreteObserver(String name, ConcreteSubject subject) {
            this.name = name;
            this.subject = subject;
        }
    
        @Override
        public void update() {
            observer_state = subject.getSubject_state();
        }
    
        public String getName() {
            return name;
        }
    
        public String getObserver_state() {
            return observer_state;
        }
    }
    public class Test {
        public static void main(String[] args) {
            ConcreteSubject subject = new ConcreteSubject();  // 具体主题
    
            ConcreteObserver observer1 = new ConcreteObserver("jzx",subject); // 观察者1
            ConcreteObserver observer2 = new ConcreteObserver("zzh",subject); // 观察者2
            subject.add(observer1);  // 具体主题注册观察者1
            subject.add(observer2);  // 具体主题注册观察者2
    
            subject.setSubject_state("发布");   // 主题改变自身状态
            subject.notifyObservers();          // 主题发布通知
            System.out.println(observer1.getName() + "的状态是:" + observer1.getObserver_state());  // 查看观察者1目前状态
            System.out.println(observer2.getName() + "的状态是:" + observer2.getObserver_state());  // 查看观察者2目前状态
    
            subject.remove(observer2);          // 主题决定不通知observer2
            subject.setSubject_state("下架");   // 主题改变自身状态
            subject.notifyObservers();         // 主题发布通知
            System.out.println(observer1.getName() + "的状态是:" + observer1.getObserver_state());  // 查看观察者1目前状态
            System.out.println(observer2.getName() + "的状态是:" + observer2.getObserver_state());  // 查看观察者2目前状态
        }
    }

    输出:

    jzx的状态是:发布

    zzh的状态是:发布

    jzx的状态是:下架

    zzh的状态是:发布

  • 相关阅读:
    【HTML5】html5在ie8及以下的兼容性问题
    【前端】从登录框看前端
    批量插入
    Mongodb地理空间索引
    Mongodb添加地理位置索引
    记一 次docker-compose build报错
    The method's class, com.google.common.collect.FluentIterable, is available from the following locations
    如果在chrome的新标签中继续打开开发工具
    设置idea 2018 的vmoptions无效
    spring boot(2):activiti整合
  • 原文地址:https://www.cnblogs.com/jiazhongxin/p/12828488.html
Copyright © 2011-2022 走看看