【观察者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现-消息
(资料图片)
观察者模式(Observer Pattern)是一种行为型模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
观察者模式使用三个类Subject、Observer和Client。Subject对象带有绑定观察者到Client对象和从Client对象解绑观察者的方法。我们创建Subject类、Observer抽象类和扩展了抽象类Observer的实体类。
作用一个对象状态更新,其他依赖对象收到通知和自动更新的机制。实现模块化分离,实现主题与观察者交互对象之间的松耦合。1)观察者定义了对象之间一对多的关系。2)被观察者(主题)用一个共同的接口来更新观察者。3)观察者和被观察者用松耦合方式结合,被观察者不知道观察者的细节,只知道观察者实现了观察者接口。实现步骤创建观察者observer基础接口,包含主题和更新方法创建主题subject抽象类,包含observer列表以及添加和删除方法创建具体的主题类,实现通知方法,发布通知时轮询通知全部观察者创建多个具体观察者,与主题关联,并实现自己的更新方法客户调用时先声明主题,再将观察者分别添加到主题,当主题发布通知时,观察者自动更新UMLJava代码观察者接口// ObserverAPI.java 观察者接口,Java 9已经默认支持Observer接口// 这里避免冲突采取ObserverAPI命名public interface ObserverAPI { public Subject subject = null; public void update(String content);}
具体观察者// ConcreteObserver.java 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。// 不同的观察者也可以对应多个主题public class ConcreteObserver implements ObserverAPI { public Subject subject; // 给观察者绑定主题,同时把观察者添加到主题列表 public ConcreteObserver(Subject subject) { this.subject = subject; this.subject.register((ObserverAPI) this); } // 观察者发出更新通知,不用单独告诉订阅者,由订阅者自行监听 public void update(String content) { System.out.println(String.format("%s::update() [subject.name = %s content = %s]", this.getClass().getName(), this.subject.getName(), content)); }}
// ConcreteObserver2.java 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。// 不同的观察者可以对应不同的主题。public class ConcreteObserver2 implements ObserverAPI { // 这里没有在构造器就绑定某个主题,而是从客户角度去注册观察者 public ConcreteObserver2() { } // 观察者发出更新通知,观察者自行监听 public void update(String content) { System.out.println(String.format("%s::update() [content = %s]", this.getClass().getName(), content)); }}
抽象主题类// Subject.java 定义抽象主题类或者接口,供具体主题类继承public abstract class Subject { private String name; // protected Set observers = new HashSet<>(); protected List observers = new ArrayList<>(); public String getName() { return name; } public void setName(String name) { this.name = name; } public void register(ObserverAPI observer) { System.out.println(this.getClass().getName() + "::register() [observer = " + observer.getClass().getSimpleName() + "]"); observers.add(observer); } public void remove(ObserverAPI observer) { observers.remove(observer); } // 通知由具体类来实现逻辑 public abstract void notify(String name);}
具体主题类// ConcreteSubject.java 观察者主题类,也是发布者,重写具体的通知方法。不同主题可以关联不同的观察者。public class ConcreteSubject extends Subject { public ConcreteSubject(String name) { this.setName(name); } // 不同的主题类有自己的通知方法,批量通知绑定的观察者 @Override public void notify(String content) { System.out.println(this.getClass().getName() + "::notify() [content = " + content + "]"); for (Object observer : this.observers) { ((ObserverAPI) observer).update(content); } }}
测试调用/** * 观察者模式应用非常广泛,主要是观察者提前绑定到发布者 * 当发布者发布消息时,批量广播通知,而无需逐一通知 * 观察者监听到消息后自己决定采取哪一种行为 */ // 定义一个主题,也就是发布者 Subject concreteSubject = new ConcreteSubject("subject1"); // 再声明观察者,通过构造器注册到主题上 ObserverAPI observer1 = new ConcreteObserver(concreteSubject); // 也可以单独给主题注册一个新的观察者 concreteSubject.register(new ConcreteObserver2()); // 可以移除观察者对象,可以打开注释试下 // concreteSubject.remove(observer1); // 主题开始发布新通知,各观察者自动更新 concreteSubject.notify("hello, this is broadcast.");
Python代码观察者接口# ObserverAPI.py 观察者抽象父类,定义一些公共方法class ObserverAPI: def __init__(self, name): self.name = name # 观察者发出更新通知,观察者自行监听 def update(self, content): print(self.__class__.__name__ + "::update() [content = " + content + "]") def set_name(self, name): self.name = name
具体观察者# ConcreteObserver.py 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。# 不同的观察者也可以对应多个主题from src.ObserverAPI import ObserverAPI# 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。# 不同的观察者也可以对应多个主题class ConcreteObserver(ObserverAPI): # 给观察者绑定主题,同时把观察者添加到主题列表 def __init__(self, subject, name): ObserverAPI.__init__(self, name) # python3支持的父类调用 # super(ConcreteObserver, self).__init__(name) # super().__init__(name) self.subject = subject subject.register(self) # 观察者发出更新通知,不用单独告诉订阅者,由订阅者自行监听 def update(self, content): print(self.__class__.__name__ + "::update() [subject.name = " + self.subject.name + " content = " + content + "]")
# ConcreteObserver2.py 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。# 不同的观察者可以对应不同的主题。from src.ObserverAPI import ObserverAPI# 具体的观察者实现类,也可以看成订阅者,关联对应的主题类。# 不同的观察者可以对应不同的主题。class ConcreteObserver2(ObserverAPI): # 这里没有在构造器就绑定某个主题,而是从客户角度去注册观察者 # 观察者发出更新通知,观察者自行监听 # def update(self, content): # print(self.__class__.__name__ + "::update() [content = " + content +"]") pass
抽象主题类# Subject.py 定义抽象主题类或者接口,供具体主题类继承class Subject: def __init__(self, name): self.name = name self.observers = [] def get_name(self): return self.name def set_name(self, name): self.name = name def register(self, observer): print(self.__class__.__name__ + "::register() [observer = " + observer.__class__.__name__ + "]") self.observers.append(observer) def remove(self, observer): self.observers.remove(observer) # 通知由具体类来实现逻辑 def notify(self, name): pass
具体主题类// ConcreteSubject.py 观察者主题类,也是发布者,重写具体的通知方法。不同主题可以关联不同的观察者。from src.Subject import Subject# 观察者主题类,也是发布者,重写具体的通知方法。不同主题可以关联不同的观察者。class ConcreteSubject(Subject): # 不同的主题类有自己的通知方法,批量通知绑定的观察者 def notify(self, content): print(self.__class__.__name__ + "::notify() [content = " + content + "]") for observer in self.observers: observer.update(content)
测试调用import sysimport osos_path = os.getcwd()sys.path.append(os_path)from src.ConcreteSubject import ConcreteSubjectfrom src.ConcreteObserver import ConcreteObserverfrom src.ConcreteObserver2 import ConcreteObserver2def test(): """ * 观察者模式应用非常广泛,主要是观察者提前绑定到发布者 * 当发布者发布消息时,批量广播通知,而无需逐一通知 * 观察者监听到消息后自己决定采取哪一种行为 """ # 定义一个主题,也就是发布者 concrete_subject = ConcreteSubject("subject1") # 再声明观察者,通过构造器注册到主题上 observer1 = ConcreteObserver(concrete_subject, "observer1") # 也可以单独给主题注册一个新的观察者 observer2 = ConcreteObserver2("observer2") concrete_subject.register(observer2) # 可以移除观察者对象 # concrete_subject.remove(observer1) # 主题开始发布新通知,各观察者自动更新 concrete_subject.notify("hello, this is broadcast.")if __name__ == "__main__": print(__file__) print("test start:") test()
更多语言版本不同语言实现设计模式:https://github.com/microwind/design-pattern
-
【观察者设计模式详解】C/Java/JS/Go/Python/TS不同语言实现-消息简介观察者模式(ObserverPattern)是一种行为型模式。它定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象
-
阿联酋与韩国两国外长通电话 呼吁苏丹冲突双方重返谈判桌|全球今亮点据阿联酋国家通讯社21日报道,当天阿联酋外交与国际合作部部长阿卜杜拉与韩国外交部长朴振通电话,讨论苏丹局势的最新进展
-
[快讯]万通液压公布2022年年度分红方案预案CFi CN讯:万通液压(股票代码:830839)公布2022年年度权益分派预案公告。根据公司2023年4月21日披露的2022年年度报告(财务报告已经
-
减持空单是什么意思_空单和多单是什么意思_当前关注1、空单:先高价卖出某品种合约,之后低价买入平仓,即先卖后买赚取差价。2、2、多单:先低价买入某品种合约,之后高价卖出该
-
全球头条:101期金原排列三预测奖号:五码直选参考上期回顾:排列三第2023100期开奖号码为632,历史上组选出现41次,直选出现8次。排列三直选632出现之后下期奖号分别为:354-635-821-421-
-
【全球独家】今日时讯:加内特利拉德半场砍41分都没出汗 太强了利拉德71分完全在常规时间砍下最后仍有时间选择不出手小伙伴们好,带大家回顾下加内特利拉德半场砍41分都没出汗太强了利拉德71分完全在常规时间砍下最后仍有时间选择不出手,那
-
【连载】拉达克往事12·文明世界的边疆(下)从帕杜姆坐车到徒步起点的查村大约需要两个半小时,从查村徒步到普克塔通常耗时两到三小时不等。所以如果早上9点吃完早饭坐车出
-
文投控股:厦门信托汇金1667号拟减持不超过2% 天天热点【文投控股:厦门信托汇金1667号拟减持不超过2%】财联社4月21日电,文投控股公告,厦门信托汇金1667号拟减持不超过
-
怎样鉴别玛瑙原石 精彩看点1、用刀子检查玛瑙的硬度,真玛瑙一般较硬,用刀子在其表面划一下,不会留下划痕,而玻璃制品则能留下痕迹。2、查看玛瑙的做工
-
当前快播:智利发布国家锂资源开发战略新华社圣地亚哥4月20日电(记者尹南张笑然)智利总统博里奇20日晚在总统府莫内达宫发表电视讲话,发布国家锂资源开发战略,宣布国家将参与锂资
-
福字门贴2023年新款_福字门贴 环球简讯你们好,最近小未来发现有诸多的小伙伴们对于福字门贴2023年新款,福字门贴这个问题都颇为感兴趣的,今天小活为大家梳理了下
-
新增21种新专业,最新大学专业热在哪?冷在哪?新增21种新专业,撤销925个专业点……近日,教育部公布了2022年度普通高等学校本科专业备案和审批结果。中国劳动关系学院官微介绍,工会学...
-
工地监理周报范文400字(必备25篇) 全球通讯工地监理周报范文400字第1篇第五周负责工程项目的内业管理工作协助项目经理做好对外协调、接待工作:协助项目经理对内协调公司、部门间,对外
-
反面教材!西媒“警告”贝林厄姆:别学姆巴佩那个叛徒,皇马不好惹欧冠就像是一块磁铁,它吸引着无数的优秀球员。皇马恰巧就是欧冠系列赛中最成功的球队,这也是许多球员渴望前往伯纳乌的原因之一。但皇马不会
-
幼儿教师招聘面试歌曲(幼儿教师招聘面试流程) 观察1、一、幼儿教师面试技巧精神紧张及克服的办法陌生的环境,被陌生的人提问,事关自己今后一段时间的发展前途,幼儿教师不可能不紧张,适度的紧
-
天天快讯:补强中卫线 阿斯顿维拉有意引进梅迪纳根据记者伊格纳奥·格努阿迪的报道,英超球队阿斯顿维拉希望在夏天签下法昆多·梅迪纳。这位23岁的球员在本赛季表现出色。欧洲各地的许多俱...
-
从业余到“转正”,《桌面地下城》的民间汉化之旅十年前Craft第一次接触《桌面地下城》的时候,他并没有想过这款游戏会伴随着他从大学走入职场,也更没有预料到他在其中的角色,会从一位用爱发
-
热点评!彩虹家族卫星直播在哪里_彩虹家族卫星直播1、麦子斜靠着它的黑暗,但时光在赶、在流逝。2、椅上的锦绸仿佛有人在酒馆斗殴中一个季节,少一些鲁莽,少一些浓郁,少一些响
-
环球最新:东方财富增资至158亿 增幅20%天眼查App显示,近日,东方财富信息股份有限公司发生工商变更,注册资本由约132 14亿人民币增至约158 57亿人民币,增幅约20%。
-
vblistbox控件使用方法_vblistbox 当前关注1、 定义变量的关键字Dim 语句Dim对象名As对象类型名 对象类型有很多,关键字如Boolean、Byte、D
-
“丹心筑梦 碧海扬帆” 中海基金2022环保·助学公益行动在沪举行 天天热门2023年4月19日,中海基金的善心大使们和上海市闵行区民办弘梅小学的师生们,在弘梅小学的校园里,共赴一场期盼已久的“爱心之约”,续写延...
-
每日速讯:智能照车牌摄像机_对于智能照车牌摄像机简单介绍1、智能照车牌摄像机主要应用于在30米的道路监控范围内,各种光线情况下都能稳定清晰地拍到彩色车牌,车身和其他运动的物体。
-
微头条丨90后,第一批接棒白酒的“年轻人”又到了每月的公司团建,“团建必喝酒”似乎已经成为了大家的共识。
-
欧洲直升机公司 全球时快讯1、欧洲直升机公司(Eurocopter)创建于1992年,现已更名为空客直升机公司,是由德国戴姆勒-克莱斯勒宇航和
-
国家中小学智慧教育平台上线高质量基础性作业-焦点短讯新京报讯据教育部网站消息,《关于进一步减轻义务教育阶段学生作业负担和校外培训负担的意见》要求将作业设计纳入教研体系,系
-
东方证券给予钢研纳克增持评级 检测、仪器业务持续发力 费用增长拖累短期业绩|每日焦点东方证券04月21日发布研报称,给予钢研纳克(300797 SZ,最新价:15 94元)增持评级。评级理由主要包括:1)22年检测业务保持较快增长、毛利率
-
十大高纤维水果 高纤维水果 天天速讯今天来聊聊关于十大高纤维水果,高纤维水果的文章,现在就为大家来简单介绍下十大高纤维水果,高纤维水果,希望对各位小伙伴们有
-
生意社:环己烷市场稳中偏强运行生意社数据显示,截止4月21日,国内工业级优等品环己烷均价在7416元 吨,本周环己烷价格走势小幅上扬,相比上周同期价格上涨1 14%,整体市场供
-
今日看点:派出所的故事:我的“话唠”师父派出所的故事:我的“话唠”师父
-
口袋妖怪究极绿宝石新紫堇神兽怎么走视频_究极绿宝石新紫堇神兽|天天快资讯1、在绿宝石中,我们需要玩完晏子城市道关,然后去大夫岩镇道关,然后去橙城,然后返回晏子市。2、而在紫堇仙灵中心前的路口,