• 浅谈Java设计模式——观察者模式(Observer)


    一、概述

            定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。所以观察者提供了一种对象设计,让主题和观察者之间以松耦合的方式结合。

    二、使用场景

    1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。 

    2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。 

    3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。

    三、参与者

    1.Subject (目标)目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。

    2.Observer (观察者)为那些在目标发生改变时需获得通知的对象定义一个更新接口。 

    3.ConcreteSubject (具体目标)将有关状态存入各ConcreteObserver对象。 当它的状态发生改变时,向它的各个观察者发出通知。 

    4.ConcreteObserver (具体观察者)维护一个指向ConcreteSubject对象的引用。 存储有关状态,这些状态应与目标的状态保持一致。 实现     Observer的更新接口以使自身状态与目标的状态保持一致

    四、类图

    五、示例代码

    1.Subject

    /**
     * Subject
     * @author zhipeng_Tong
     */
    public abstract class Subject {
        private ArrayList<Observer> observers = new ArrayList<>();
    
        // 添加观察者
        public void add(Observer observer) {
            observers.add(observer);
        }
    
        // 移除观察者
        public void remove(Observer observer) {
            observers.remove(observer);
        }
    
        // 通知
        public void toNotify() {
            for (Observer observer : observers)
                observer.update();
        }
    }

    2.Observer

    /**
     * Observer
     * @author zhipeng_Tong
     */
    public interface Observer {
        void update();
    }

    3.ConcreteSubject

    /**
     * ConcreteSubject
     * @author zhipeng_Tong
     */
    public class Boss extends Subject {
        private String subjectState;    // 保存状态信息
    
        public String getSubjectState() {
            return subjectState;
        }
    
        public void setSubjectState(String subjectState) {
            this.subjectState = subjectState;
        }
    }

    4.ConcreteObserver 

    /**
     * ConcreteObserver
     * @author zhipeng_Tong
     */
    public class StockObserver implements Observer {
        private String name;    // 名称
        private String observerState;   // 状态
        private Boss subject;    // 通知者
    
        public StockObserver(String name, Boss subject) {
            this.name = name;
            this.subject = subject;
        }
    
        @Override
        public void update() {
            observerState = subject.getSubjectState();
            System.out.println(String.format("%s - %s 关闭股票软件,继续工作。", observerState, name));
        }
    }

    5.测试代码

    public class Client {
        public static void main(String[] args) {
            Boss boss = new Boss();
    
            boss.add(new StockObserver("李传华", boss));
            boss.add(new StockObserver("周大海", boss));
    
            boss.setSubjectState("老板回来了");
            boss.toNotify();
        }
    }

    运行结果:

    老板回来了 - 李传华 关闭股票软件,继续工作。
    老板回来了 - 周大海 关闭股票软件,继续工作。
  • 相关阅读:
    Web项目发布步骤总结
    Web项目发布的一些设置
    阿里云部署Web项目
    Tomcat、Weblogic、WebSphere、JBoss服务器的选择
    EJB到底是什么
    数据库线程池3——现实中的参数
    数据库线程池2——线程池调优
    数据库线程池1——三种线程池的参数详细
    Mysql分页优化
    org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'cardSalDao' defined in file [E:GItUppointerCard+redis argetgameCard-1.0-SNAPSHOTWEB-INFclassescnjbitdao
  • 原文地址:https://www.cnblogs.com/IdealSpring/p/11871163.html
Copyright © 2020-2023  润新知