• 《大话设计模式》——观察者模式(订阅--发布模式)


    观察者模式结构图:

    从上图中可以看到观察者模式需要4个角色:

    1.Observer:抽象观察者。

    2.ConcreteObserver:具体观察者。

    3.Subject:抽象通知者。

    4.ConcreteSubject:具体通知者。

    这里我们用上班玩手机来举例:有几个同事每天在公司的状态为“玩手机”,然后为了不给老板发现,安排了一个靠近大门的同事当他们的通知者,当老板走入大门的时候,这个同事就要马上通知他们,他们会更新状态为“工作”。假如这个同事没有及时通知他们,那么通知者就会变成老板,老板当场抓获他们的状态为“玩手机”,同时还要当场批评。

    下面我们通过代码来进行实现:

    1.定义抽象观察者同事Observer,里面只有一个方法update用来更新状态:这里定义接口的意义在于遵循“开放--封闭原则”,如果有新的偷偷看电影的同事,也可以实现接口,保证对观察者对象的内部一致性。

    public interface Observer {
    
        void update(String state);
    
    }

    2.定义具体的观察者同事ConcreteObserver:

    public class ConcreteObserver implements Observer {
    
        private String state = "玩手机"; //默认在玩手机
    
        @Override
        public void update(String state) { //由坐在靠窗位置的同事进行通知,通知后马上修改状态。
            this.state = state;
        }
    
    }

    3.定义抽象通知者同事:这里接口的定义同样是为了满足"开放—封闭原则",因为通知者有可能是靠窗的同事,也可能是被老板给抓了现场。

    public interface Subject {
    
        void add(Observer observer); //添加通知的同事
    
        void remove(Observer observer); //移除通知的同事
    
        void notice(String notice); //通知同事
    }

    4.定义具体的通知者同事:这里只定义了通知者同事,没有定义通知者老板,老板类似,只不过会多一个扣除工资的操作。

    public class ConcreteSubject implements Subject {
    
        private List<Observer> list = new ArrayList<>();
    
        @Override
        public void add(Observer observer) {
            list.add(observer);
        }
    
        @Override
        public void remove(Observer observer) {
            list.remove(observer);
        }
    
        @Override
        public void notice(String notice) {
            for (Observer observer : list) {
                observer.update("工作!");
            }
        }
    }

    5.客户端:实际流程开始了

    public class Main8 {
    
        public static void main(String[] args) {
            Subject subject1 = new ConcreteSubject(); //通知者同事
            Observer observer1 = new ConcreteObserver(); //观察者同事1
            Observer observer2 = new ConcreteObserver(); //观察者同事2
            Observer observer3 = new ConcreteObserver(); //观察者同事3
    
            //将同事添加到通知对象里面来
            subject1.add(observer1);
            subject1.add(observer2);
            subject1.add(observer3);
    
            // 老板来了,赶紧通知工作!
            subject1.notice("工作!");
        }
    
    }

    特点:

    将一个复杂系统分成几个小模块后,需要在这几个模块中保持一致性,但是又不能让他们进行紧耦合。此时可以通过观察者模式,又称订阅—发布模式,令这几个模块都订阅某一事件,当事件发生后,通知模块会对订阅了这一事件的模块分别进行通知,以让他们保持一致性。

  • 相关阅读:
    EF6.0新特性-DbCommandInterceptor实现非SQL端读写分离
    【转】VS2012 中文版转英文版 英文版转中文版 界面语言切换
    【转】Repository 返回 IQueryable?还是 IEnumerable?
    迟来的零碎笔记
    mysql 列转行,合并字段的方法
    MySQL 5.7.9版本sql_mode=only_full_group_by问题
    mysql实现full outer join
    ubuntu下如何查找某个文件的路径
    mysql之group_concat函数详解
    MySQL 表别名(Alias)
  • 原文地址:https://www.cnblogs.com/yxth/p/10832946.html
Copyright © 2020-2023  润新知