观察者模式(Observer Pattern)

来源:互联网 发布:visio mac版 编辑:程序博客网 时间:2024/06/16 21:36

观察者模式(Observer Pattern)

观察者模式(Observer Pattern)也叫发布订阅模式(Publish/subscribe),它是一个在项目中经常 的模式,其定义如下:
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically. (定义对象间一种“一对多”的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新)
观察者的通用类图

  • Subject 被观察者
    定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。
  • Observer观察者
    观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。
  • ConcreteSubject具体的被观察者
    定义被观察者自己的业务,同时定义对哪些事件行通知。
  • ConcreteObserver具体的观察者
    每个观察者在接收到消息后的处理反应是不同的,各个观察者有自己的处理逻辑。

观察者模式的优点
1. 观察者和被观察者之间是抽象耦合
如何设计,则不 管是增加观察者还是被观察者都非常容易,而且在Java中都已经被盖同的层级的定义,在系统方面更是得心应手。
2. 建立一套触发机制
根据单一职责原则,每个类的职责是单一的,那么怎么把这个单一的串联成真实世界的复杂逻辑关系呢?比如我们去打猎,打死了一只母鹿,母鹿有三个幼崽,因后援会以了母鹿而饿死,继而……然后……这就是一个触发机制,形成了一个触发链。观察者模式可以完美实现这里的链条形式。

观察者模式的缺点
观察者模式需要考虑一下开发效率和运行效率量,一个空间站以者,多个观察者,开发和高度就会比较复杂,而且Java中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。
多级触发时的效率更是让人担忧,大家在设计时注意考虑。

观察者模式的使用场景
1. 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
2. 事件多级触发场景。
3. 跨系统的消息交换场景,如消息队列的处理机制。


Subject类

package patterns.Observer.useUtil;import java.util.Observable;public class 信息暴露狂 extends Observable {    private int 道德 = 50;    private int 智商 = 50;    private int 体重 = 50;    public 信息暴露狂() {        System.out.println("我是暴露狂,我做什么事都要让别人知道!!!");    }    @Override    public String toString() {        return "目前此人 道德"+道德+" 智商"+智商+" 体重"+体重;    }    public void 吃() {        System.out.println("我吃");        体重++;        setChanged();       //此处不调不触发下一句事件!!!!特别注意!!!        this.notifyObservers("各种美拍高大上");    }    public void 喝() {        System.out.println("我喝");        体重++;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 拉() {        System.out.println("我拉");        体重--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 撒() {        System.out.println("我撒");        体重--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 睡() {        System.out.println("我睡");        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 坑() {        System.out.println("我坑");        道德--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 蒙() {        System.out.println("我蒙");        智商--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 拐() {        System.out.println("我拐");        体重--;        道德--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 骗() {        System.out.println("我骗");        智商++;        道德--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 偷() {        System.out.println("我偷");        体重--;        道德--;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public void 学习() {        System.out.println("我学习");        智商++;        道德++;        setChanged();        this.notifyObservers("各种美拍高大上");    }    public int get道德() {        return 道德;    }    public int get智商() {        return 智商;    }    public int get体重() {        return 体重;    }}

Main

package patterns.Observer.useUtil;import java.util.Observable;import java.util.Observer;public class Client {    //观察者模式执行场景    public static void main(String[] args) {        Observer 朋友圈 = new Observer() {            @Override            public void update(Observable o, Object arg) {                //处理传来的值                if(o instanceof 信息暴露狂){                    信息暴露狂 human = (信息暴露狂)o;                    //“拉”信息                    int 道德 = 10*human.get道德();                    int 智商 = 10*human.get智商();                    int 体重 = 10*human.get体重();                    String after = arg+"加道德"+道德+"、加智商"+智商+"、加体重"+体重+"=====";                    System.out.println("发到【朋友圈】:"+after+" - "+o);                }            }        };        Observer 微博 = new Observer() {            @Override            public void update(Observable o, Object arg) {                //“推”信息                System.out.println("发到【微博】:"+arg+" - "+o);            }        };        信息暴露狂  老陈头 = new 信息暴露狂();        老陈头.addObserver(朋友圈);        老陈头.吃();        老陈头.喝();        老陈头.addObserver(微博);    //拉巴巴的时候注册了微博        老陈头.拉();        老陈头.撒();        老陈头.睡();        老陈头.坑();        老陈头.deleteObserver(朋友圈);    //不再玩朋友圈了        老陈头.蒙();        老陈头.拐();        老陈头.骗();        老陈头.偷();        老陈头.学习();    }}

运行结果

我是暴露狂,我做什么事都要让别人知道!!!
我吃
发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重510===== - 目前此人 道德50 智商50 体重51
我喝
发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重520===== - 目前此人 道德50 智商50 体重52
我拉
发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重51
发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重510===== - 目前此人 道德50 智商50 体重51
我撒
发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重50
发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重500===== - 目前此人 道德50 智商50 体重50
我睡
发到【微博】:各种美拍高大上 - 目前此人 道德50 智商50 体重50
发到【朋友圈】:各种美拍高大上加道德500、加智商500、加体重500===== - 目前此人 道德50 智商50 体重50
我坑
发到【微博】:各种美拍高大上 - 目前此人 道德49 智商50 体重50
发到【朋友圈】:各种美拍高大上加道德490、加智商500、加体重500===== - 目前此人 道德49 智商50 体重50
我蒙
发到【微博】:各种美拍高大上 - 目前此人 道德49 智商49 体重50
我拐
发到【微博】:各种美拍高大上 - 目前此人 道德48 智商49 体重49
我骗
发到【微博】:各种美拍高大上 - 目前此人 道德47 智商50 体重49
我偷
发到【微博】:各种美拍高大上 - 目前此人 道德46 智商50 体重48
我学习
发到【微博】:各种美拍高大上 - 目前此人 道德47 智商51 体重48

0 0