首页 > 技术文章 > 《大话设计模式》——观察者模式(订阅--发布模式)

yxth 2019-05-08 16:57 原文

观察者模式结构图:

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

}

 

特点:

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

 

推荐阅读