Java设计模式--观察者模式

1 Observer Pattern 观察者模式

目的:用于建立一种对象与对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应作出反应;
实现:不关心生成产品的具体实现,只关心接口,仅使用接口生成产品。

1.描述了如何建立对象与对象之间的依赖关系,以及如何构造满足这种需求的系统,包括观察目标和观察者两个继承层次结构;
2.发生改变的对象称为观察目标,而被通知的对象称为观察者,一个观察目标可以对应多个观察者,而且这些观察者之间可以没有任何相互联系,可以根据需要增加和删除观察者,使得系统更易于扩展;
3.在 JDK 的 java.util 包中,提供了 Observable 类以及 Observer 接口,它们构成了 JDK 对观察者模式的支持。

2 实现

代码场景:无间道中韩琛带着众小弟跟泰国佬交易的场景,:
1.年产100万吨级别的金日成造船厂;
2.年产500万吨的金正日钢铁厂;
3.生产各种面包的金正恩面包厂。

2.1 代码实现

目标抽象类

public abstract class AbstractRingleader {
    protected List<AbstractObserver> observers = new ArrayList<AbstractObserver>();
    //情报人员暗中监视
    public void addobservers(AbstractObserver Observer) {
        observers.add(Observer);
    }
    //情报人员不再监视
    public void deleteobservers(AbstractObserver Observer) {
        observers.remove(Observer);
    }
    // 目标人物的行动
    public abstract void notifys();

}

具体的目标:老大韩琛

public class HanChen extends AbstractRingleader {

    @Override
    public void notifys() {
        System.out.println("--------镜头一-------");
        System.out.println("韩琛和泰国佬寒暄之后,让陈永仁验了货后,
            就打电话给在码头的傻强收货~");
        for (AbstractObserver observer : observers) {
            observer.sendIntelligence();
        }
    }
}

观察者抽象类

public abstract class AbstractObserver {
    //发送情报
    public abstract void sendIntelligence();
}

具体的观察者:卧底 陈永仁

public class ChenYongRen extends AbstractObserver {

    @Override
    public void sendIntelligence() {
        System.out.println("--------镜头二-------");
        System.out.println("陈永仁验货后就溜到窗户边,偷偷的听着韩琛说话...");
        System.out.println("用打着石膏的手,在窗户边上悄悄的发出收货地址的摩斯码~");

    }

}

具体的观察者:黄Sir

public class HuangSir extends AbstractObserver {

    @Override
    public void sendIntelligence() {
        System.out.println("--------镜头三-------");
        System.out.println("从监控中看到了韩琛他们在密谈,又收到了陈永仁发来的收货地址,命令手下抓人~");
    }

}

2.2 涉及角色

在观察者模式结构图中包含如下几个角色:

Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法 notify()。目标类可以是接口,也可以是抽象类或具体类。

ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。

扫描二维码关注公众号,回复: 131163 查看本文章

Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法update(),因此又称为抽象观察者。

ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者 Observer 中定义的 update() 方法。通常在实现时,可以调用具体目标类的 attach() 方法将自己添加到目标类的集合中或通过 detach() 方法将自己从目标类的集合中删除。

2.3 调用

调用者:

public class Client {

    public static void main(String[] args) {
        System.out.println("剧情: 韩琛出场");
        AbstractRingleader hanChen = new HanChen();
        System.out.println("剧情: 陈永仁 跟着 韩琛");
        AbstractObserver chenYongRen = new ChenYongRen();
        System.out.println("剧情: 黄Sir 在对面楼上注视着交易现场");
        AbstractObserver hanSir = new HuangSir();
        System.out.println("-------------------");
        System.out.println("剧情: 韩琛在不知道的情况下被监视");
        hanChen.addobservers(chenYongRen);
        hanChen.addobservers(hanSir);
        //韩琛的确认收货 触发了两个监视着的行为
        hanChen.notifys();
    }
}

结果:

剧情: 韩琛出场
剧情: 陈永仁 跟着 韩琛
剧情: 黄Sir 在对面楼上注视着交易现场
-------------------
剧情: 韩琛在不知道的情况下被监视
--------镜头一-------
韩琛和泰国佬寒暄之后,让陈永仁验了货后,就打电话给在码头的傻强收货~
--------镜头二-------
陈永仁验货后就溜到窗户边,偷偷的听着韩琛说话...
用打着石膏的手,在窗户边上悄悄的发出收货地址的摩斯码~
--------镜头三-------
从监控中看到了韩琛他们在密谈,又收到了陈永仁发来的收货地址,命令手下抓人~

代码地址:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

猜你喜欢

转载自blog.csdn.net/weixx3/article/details/80202239