观察者模式 墨蓝 2022-03-15 06:48 259阅读 0赞 ## 前言 ## 观察者模式还算一个比较好玩的设计模式,其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。可以想象成消息中间件在系统中的作用。SpringBoot启动就是使用了观察者模式。 这是我最近阶段最后一次更新设计模式的文章了,我要去把精力放到其他地方,有感兴趣的小伙伴可以在下方留言,或者加公众号留言,我会回复你的,也可以直接在我的主页找微信二维码添加好友,让我们一同进步。 大家学过设计模式后要切记不是设计模式用的越多系统越好,不适合的不要强加过去,本来很简单的逻辑那么咱们就不要大费周折,设计模式的其中一点就是解决代码复用性,如果违背了就不好了。千万别拿着锤子看哪都像钉子啊,就好比学了分布式事务的解决方案就想在系统里应用,其实有的时候我们大可避免产生分布式事务的问题的,题外话题外话。 ## 正文 ## 概念:对象间的一对多的依赖关系。 网上这个概念说的太宽泛了。我找了一个图,请看 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70][] 还有一个图,也可以帮助大家理解 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 1][] 首先,观察者是一种面向接口编程, **在观察者模式结构图中包含如下几个角色** ● Subject(目标):目标又称为主题,它是指被观察的对象。在目标中定义了一个观察者集合,一个观察目标可以接受任意数量的观察者来观察,它提供一系列方法来增加和删除观察者对象,同时它定义了通知方法notify()。目标类可以是接口,也可以是抽象类或具体类。 ● ConcreteSubject(具体目标):具体目标是目标类的子类,通常它包含有经常发生改变的数据,当它的状态发生改变时,向它的各个观察者发出通知;同时它还实现了在目标类中定义的抽象业务逻辑方法(如果有的话)。如果无须扩展目标类,则具体目标类可以省略。 ● Observer(观察者):观察者将对观察目标的改变做出反应,观察者一般定义为接口,该接口声明了更新数据的方法collect(),因此又称为抽象观察者。 ● ConcreteObserver(具体观察者):在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要和具体目标的状态保持一致;它实现了在抽象观察者Observer中定义的collect()方法。 总之这些概念我是看的不舒服,看不懂没关系,我简单说一下吧。一共四个类。两个接口,两个接口实现类, * 被观察者方法参数引用的是观察者对象。 * 观察者只定义一个自己的行为。 * 具体观察者重写观察者的行为后还提供了构造方法为客户端调用。 * 具体被观察者,这个类有些复杂,简单的说就是把外界消息通过该类的方法调用 notifyObserver()方法给提前准备好的Observer(观察者)接口中的方法去发送。 ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 2][] 代码解释 **Subject** public interface Subject { //添加观察者 void addObserver(Observer o); //移除观察者 void removeObserver(Observer o); //通知观察者方法 void notifyObserver(); } **Observer** public interface Observer { //观察者有只有收信息的行为 void collect(String message); } **具体观察者 ** public class User implements Observer { private String name; private String message; public User(String name) { this.name = name; } public void collect(String message) { this.message = message; read(); } //观察者的实际行为 public void read() { System.out.println(name + " 收到推送消息: " + message); } } **具体被观察者** //被观察者的实现类,也就是微信公众号服务 public class WeChatServer implements Subject { //注意到这个List集合的泛型参数为Observer接口,设计原则:面向接口编程而不是面向实现编程 private List<Observer> list = new ArrayList<Observer>(); private String message; public void addObserver(Observer o) { list.add(o); } public void removeObserver(Observer o) { if (!list.isEmpty()) list.remove(o); } //把消息发给每一个订阅的观察者 public void notifyObserver() { for (int i = 0; i < list.size(); i++) { Observer observer = list.get(i); observer.collect(message); } } public void setInformation(String s) { this.message = s; System.out.println("微信服务更新消息: " + s); //消息更新,通知所有观察者 notifyObserver(); } } **测试** public class ObserverTest { public static void main(String[] args) { WeChatServer server = new WeChatServer(); Observer userA = new User("a"); Observer userB = new User("b"); Observer userC = new User("c"); server.addObserver(userA); server.addObserver(userB); server.addObserver(userC); server.setInformation("PHP是世界上最好用的语言!"); System.out.println("----------------------------------------------"); server.removeObserver(userA); server.setInformation("放屁,JAVA是世界上最好用的语言!"); } } **输出结果** ![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 3][] 在以下情况下可以考虑使用观察者模式: (1) 一个抽象模型有两个方面,其中一个方面依赖于另一个方面,将这两个方面封装在独立的对象中使它们可以各自独立地改变和复用。 (2) 一个对象的改变将导致一个或多个其他对象也发生改变,而并不知道具体有多少对象将发生改变,也不知道这些对象是谁。 (3) 需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。 比如有订阅性质的,发布性质的都可以使用。 参考文献: * [https://segmentfault.com/a/1190000012295887][https_segmentfault.com_a_1190000012295887] * [https://www.cnblogs.com/renhui/p/6479748.html][https_www.cnblogs.com_renhui_p_6479748.html] * [https://www.cnblogs.com/fingerboy/p/5468994.html][https_www.cnblogs.com_fingerboy_p_5468994.html] * [https://www.cnblogs.com/luohanguo/p/7825656.html][https_www.cnblogs.com_luohanguo_p_7825656.html] ![20190301154800233.jpeg][]![watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 4][] [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70]: /images/20220315/858f4ecc1b2d40f08d728442c939dd2d.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 1]: /images/20220315/9142f86e2e0742a381af2d16848b14cc.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 2]: /images/20220315/c05b23bf124b4b819ac2f1dc314be51e.png [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 3]: /images/20220315/f26d2d5467064435ada0529e97aad177.png [https_segmentfault.com_a_1190000012295887]: https://segmentfault.com/a/1190000012295887 [https_www.cnblogs.com_renhui_p_6479748.html]: https://www.cnblogs.com/renhui/p/6479748.html [https_www.cnblogs.com_fingerboy_p_5468994.html]: https://www.cnblogs.com/fingerboy/p/5468994.html [https_www.cnblogs.com_luohanguo_p_7825656.html]: https://www.cnblogs.com/luohanguo/p/7825656.html [20190301154800233.jpeg]: https://img-blog.csdnimg.cn/20190301154800233.jpeg [watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8zODAwMzM4OQ_size_16_color_FFFFFF_t_70 4]: /images/20220315/8689ad0cd14f4fe1bc9b4399775dc213.png
相关 观察者模式 什么是观察者模式 有人这么说 > 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。 > > 这个主题对象在状态上发生变化时,会通知所有观 梦里梦外;/ 2022年07月20日 12:05/ 0 赞/ 207 阅读
相关 观察者模式 观察者模式:定义了对象之间的一对多的依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新。 观察者模式图: ![输入图片说明][13105107_Mf 旧城等待,/ 2022年06月03日 02:41/ 0 赞/ 210 阅读
相关 观察者模式 前言 观察者模式还算一个比较好玩的设计模式,其实就是发布订阅模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。可以想象成消息中间件在系统中的作 墨蓝/ 2022年03月15日 06:48/ 0 赞/ 260 阅读
相关 观察者模式 类似于广播,目标对象的状态改变后,所有观察者的状态随之改变 步骤: 目标类中有一个属性是一个集合, 有一个注册方法,所有观察者使用前都要注册。 有一个 ╰半橙微兮°/ 2022年02月01日 15:43/ 0 赞/ 179 阅读
相关 观察者模式 什么是观察者模式? 简单的来说,观察者模式=出版者+订阅者。用比较书面的话来说的话是:定义了对象之间的一对多依赖,当一所对应的对象状态改变时,它的所有依赖者都会收到通知并 你的名字/ 2022年02月01日 13:53/ 0 赞/ 322 阅读
相关 观察者模式 前言 观察者模式又叫发布-订阅(Publish/Subscribe)模式 观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个 本是古典 何须时尚/ 2021年12月09日 00:47/ 0 赞/ 278 阅读
相关 观察者模式 case ![18721752-ed32bda3ae538d1f.png][] image.png 非设计模式code SimpleWeatherDat 朱雀/ 2021年09月18日 07:26/ 0 赞/ 401 阅读
相关 观察者模式 当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。 意图:定义对象 系统管理员/ 2021年09月17日 01:36/ 0 赞/ 416 阅读
相关 观察者模式 15.观察者模式 ![70][] public abstract class Blog// 订阅号抽象类 { priva 布满荆棘的人生/ 2021年09月17日 00:04/ 0 赞/ 374 阅读
相关 观察者模式 一 点睛 定义 又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态 ﹏ヽ暗。殇╰゛Y/ 2021年07月24日 14:52/ 0 赞/ 410 阅读
还没有评论,来说两句吧...