zoukankan      html  css  js  c++  java
  • 《大话设计模式》——观察者模式(订阅--发布模式)

    观察者模式结构图:

    从上图中可以看到观察者模式需要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("工作!");
        }
    
    }

    特点:

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

  • 相关阅读:
    一些有关时间的获取
    Devexpress xaf用代码打开菜单(Navigation Item)
    Devexpress xaf BO中字段为RuleRequiredField必输字段时,文本标签默认添加*标记
    Devepxress xaf Dashboard中DetailView控件使其可编辑
    Devexpress WinForm TreeList的三种数据绑定方式(DataSource绑定、AppendNode添加节点、VirtualTreeGetChildNodes(虚拟树加载模式))
    Devexpress xaf针对某个用户登录后在面板中设置导航无效的解决方法
    IIS不能下载config配置文件的解决方法
    DevExpress WPF控件记录
    Devexpress WinForm GridControl实现单元格可编辑状态更改
    Devexpress GridControl中 repositoryItemCheckEdit作为选择列以及作为显示列的使用方法
  • 原文地址:https://www.cnblogs.com/yxth/p/10832946.html
Copyright © 2011-2022 走看看