设计模式系列之「观察者模式」

最近小Y在看《反黑》这部剧,最引人回味的是堪称经典的山鸡哥飞上枝头变凤凰,当初的古惑仔弃暗投明做警察,可谓是涅槃重生啊。

张sir:山鸡,和兴盛最近很嚣张啊,该是你大展身手的时候了,你要以最短时间打入他们内部获取犯罪证据,同时你要更名为凤凰,UnderStand?

凤凰仔:Yes,Sir。

经过一段时间潜伏,凤凰哥终于打入和兴盛内部,成为韩彬的一把手。时刻监视着大佬们的一举一动。

凤凰仔:张sir,和兴盛大佬们齐聚一起,准备搞场大龙凤,你立马拖班人马过来压压惊,顺便来了一锅端。

根据凤凰监提供的证据,警方成功把这个社团搞得鸡飞狗跳。最后凤凰仔用枪指着韩彬的头来了一句:一直在你身边的警察,是我。来了一个一百八十度的转弯,山鸡变凤凰。

凤凰哥、Laughing哥是港剧卧底的佼佼者,让人赞不绝口。在设计模式中,照样有充当这样角色的存在——观察者模式

一、基本概念

1.定义

观察者模式也叫做发布订阅模式,定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。

2.角色介绍

  • Subject被观察者
    定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观察者。

  • Observer观察者
    观察者接收到消息后,即进行update(更新方法)操作,对接收到的信息进行处理。

  • ConcreteSubject具体的被观察者
    定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

  • ConcreteObserver具体的观察者
    每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。

3.观察者模式的使用场景

  • 跨系统的消息交换场景,如消息队列的处理机制。
  • 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。
  • 事件多级触发场景。

二、观察者模式演绎山鸡变凤凰

在反黑组在监视这几位大佬的同时,商业调查科等等其他警察部门也在监视着,为了使各部门行动统一,凤凰仔收集到的证据统一使用,根据其反馈回来的消息,各部门做相应的准备。

1.具体角色分配UML

2.代码实现

①和兴盛的抽象被观察者

public abstract class HeXingSheng {

    //保存监视和兴的警察部门
    private List<Police> polices=new ArrayList<>();
    //增加监听的警察部门
    public abstract void addPoliceObserver(Police police);
    //删除监听的警察部门
    public abstract void deletePoliceObserver(Police police);
    //通知每个监听部门作出反应
    public abstract void notifyPolices(String tip);

}

②和兴盛大佬们的具体被观察类

public class HeadOfGang extends HeXingSheng {
    @Override
    public void addPoliceObserver(Police police) {
        this.polices.add(police);
    }

    @Override
    public void deletePoliceObserver(Police police) {
        this.polices.remove(police);
    }

    @Override
    public void notifyPolices(String tip) {
        for(Police police:polices){
            police.action(tip);
        }
    }
}

③警察部门的抽象观察者

public abstract class Police {
    //根据信息作出反应
    public abstract void action(String action);
}

④反黑组

public class FanHeiTeam extends Police {
    @Override
    public void action(String action) {
        System.out.println("卧底凤凰提供的情报:"+action);
        System.out.println("反黑组根据情报对和兴盛进行相关黑社会行为进行控告。");
    }
}

⑤商业调查科

public class ShangYeTeam extends Police{

    @Override
    public void action(String action) {
        System.out.println("卧底凤凰提供的情报:"+action);
        System.out.println("商业调查科根据情报对和兴盛进行相关商业行为进行控告。");
    }
}

⑥Client

public class Client {

    public static void main(String[] args) {
        //被观察的对象-和兴盛
        HeXingSheng xingSheng=new HeadOfGang();
        //观察对象-反黑组、商业调查科
        Police fanHeiTeam=new FanHeiTeam();
        Police shangye=new ShangYeTeam();
        //增加观察者
        xingSheng.addPoliceObserver(fanHeiTeam);
        xingSheng.addPoliceObserver(shangye);
        //凤凰仔收集到证据,通知各部门准备行动
        xingSheng.notifyPolices("和兴盛大佬们聚在一起搞龙凤。");
    }
}

输出的结果为:

//反黑组 
卧底凤凰提供的情报:和兴盛大佬们聚在一起搞龙凤。
反黑组根据情报对和兴盛进行相关黑社会行为进行控告。

//商业调查科
卧底凤凰提供的情报:和兴盛大佬们聚在一起搞龙凤。
商业调查科根据情报对和兴盛进行相关商业行为进行控告。

三、观察者模式优缺点

1.优点

  • 观察者模式支持广播通信。被观察者会向所有的登记过的观察者发出通知。
  • 观察者和被观察者之间是抽象耦合。则不管是增加观察者还是被观察者都非常容易扩展,而且在Java中都已经实现的抽象层级的定义,在系统扩展方面更是得心应手。

2.缺点

  • 如果一个被观察者对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间,效率让人担忧。

  • 一个被观察者,多个观察者,开发和调试就会比较复杂,而且在Java中消息的通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。在这种情况下,一般考虑采用异步的方式。

四、总结

观察者模式在项目中非常常用,但是从上面页面知道观察者模式也相对存在着缺点,一是广播链的问题。另外一个就是异步处理问题,在开发中需要格外注意。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,547评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,399评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,428评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,599评论 1 274
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,612评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,577评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,941评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,603评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,852评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,605评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,693评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,375评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,955评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,936评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,172评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,970评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,414评论 2 342

推荐阅读更多精彩内容