无锡高端网站设计,利用网站做蜘蛛池,asp汽车租凭网站源码,邯郸建设公司网站简介
观察者模式#xff08;Observer Pattern#xff09;是一种行为型模式。它定义对象间的一种一对多的依赖关系#xff0c;当一个对象的状态发生改变时#xff0c;所有依赖于它的对象都得到通知并被自动更新。
观察者模式使用三个类Subject、Observer和Client。Subject…简介
观察者模式Observer Pattern是一种行为型模式。它定义对象间的一种一对多的依赖关系当一个对象的状态发生改变时所有依赖于它的对象都得到通知并被自动更新。
观察者模式使用三个类Subject、Observer和Client。Subject对象带有绑定观察者到Client对象和从Client对象解绑观察者的方法。我们创建Subject类、Observer抽象类和扩展了抽象类Observer的实体类。
作用
一个对象状态更新其他依赖对象收到通知和自动更新的机制。实现模块化分离实现主题与观察者交互对象之间的松耦合。 1观察者定义了对象之间一对多的关系。 2被观察者(主题)用一个共同的接口来更新观察者。 3观察者和被观察者用松耦合方式结合被观察者不知道观察者的细节只知道观察者实现了观察者接口。
实现步骤
创建观察者observer基础接口包含主题和更新方法创建主题subject抽象类包含observer列表以及添加和删除方法创建具体的主题类实现通知方法发布通知时轮询通知全部观察者创建多个具体观察者与主题关联并实现自己的更新方法客户调用时先声明主题再将观察者分别添加到主题当主题发布通知时观察者自动更新
UML Java代码
观察者接口 // 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 SetObserverAPI observers new HashSet();protected ListObserverAPI 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);}// 不同的主题类有自己的通知方法批量通知绑定的观察者Overridepublic 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 subjectsubject.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 nameself.observers []def get_name(self):return self.namedef set_name(self, name):self.name namedef 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