资讯专栏INFORMATION COLUMN

轻松学会观察者模式

hightopo / 2633人阅读

摘要:观察者模式当对象间存在一对多关系时,则使用观察者模式。观察者模式属于行为型模式。观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

观察者模式

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。

介绍

意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。

何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。

如何解决:使用面向对象技术,可以将这种依赖关系弱化。

应用实例:1.拍卖的时候,拍卖师观察最高标价,然后通知给其他竞价者竞价。
2.打团时每个职业做不同的事情。

优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。

缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。

简单的说就是:多个对象去观察一个对象是否发出号令(消息),然后做出相应响应动作

以DNF打团为例子:
当团长发出攻坚开始的消息时所有的队友开始输出。

创建一个职业的抽象类(观察者接口):Hero

public abstract class Hero {

    /**
     * 打团
     * @param msg
     */
    public abstract void datuan(String msg);

}
分别创建三个职业(观察者)

创建一个红眼:Hongyan

public class Hongyan extends Hero {

    private static final String ROLE = "帝血弑天";

    @Override
    public void datuan(String msg) {
        System.out.println(msg+ ROLE +":血魔:弑天! ");
    }
}

创建一个奶爸:Naiba

public class Naiba extends Hero {

    private static final String ROLE = "神思者";

    @Override
    public void datuan(String msg) {
        System.out.println(msg + ROLE + ": 阿波克列!");
    }
}

创建一个篮拳:Lanquan

public class Lanquan extends Hero {

    private static final String ROLE = "正义仲裁者";

    @Override
    public void datuan(String msg) {
        System.out.println(msg+ ROLE + ":粉碎吧!");
    }
}

创建一个团长(被观察者):Captain

public class Captain {

    private List heroes = new ArrayList<>();

    public void setMsg(String msg) {
        notifyAll(msg);
    }
    //订阅
    public void addTeam(Hero hero) {
        heroes.add(hero);
    }
    //通知所有订阅的观察者
    private void notifyAll(String msg) {
        for (Hero observer : heroes) {
            observer.datuan(msg);
        }
    }


}

主程序:Main

public class Main {

    public static void main(String[] args) {
        Lanquan lanquan = new Lanquan();
        Hongyan hongyan = new Hongyan();
        Naiba naiba = new Naiba();

        Captain captain = new Captain();
        captain.addTeam(lanquan);
        captain.addTeam(hongyan);
        captain.addTeam(naiba);
        captain.setMsg("超时空攻坚战开始-");

    }

}

执行结果:

超时空攻坚战开始-正义仲裁者:粉碎吧!
超时空攻坚战开始-帝血弑天:血魔:弑天! 
超时空攻坚战开始-神思者: 阿波克列!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/73582.html

相关文章

  • 轻松学会责任链模式

    摘要:设计模式责任链模式顾名思义,责任链模式为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。 设计模式 - 责任链模式 顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型...

    cheukyin 评论0 收藏0
  • 轻松学会代理模式

    摘要:在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。注意事项和适配器模式的区别适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。和装饰器模式的区别装饰器模式为了增强功能,而代理模式是为了加以控制。 代理模式 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。 在代理模式中,我们创建具有现有对象的对象...

    Ali_ 评论0 收藏0
  • 前端基础进阶(六):在chrome开发者工具中观察函数调用栈、作用域链与闭包

    摘要:在的开发者工具中,通过断点调试,我们能够非常方便的一步一步的观察的执行过程,直观感知函数调用栈,作用域链,变量对象,闭包,等关键信息的变化。其中表示当前的局部变量对象,表示当前作用域链中的闭包。 showImg(https://segmentfault.com/img/remote/1460000008404321); 在前端开发中,有一个非常重要的技能,叫做断点调试。 在chrome...

    draveness 评论0 收藏0

发表评论

0条评论

hightopo

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<