设计模式--观察者模式
创始人
2024-03-22 12:40:59
0

文章目录

  • 前言
  • 一、未使用设计模式
  • 二、观察者模式
    • 1.定义
    • 2.组成
  • 三、应用场景
  • 四、优缺点


前言

甲人A(产品经理):好啊,你小子,又被我逮到了,很闲是吧😇,需求完成了吗?
two days later…

芯不小:猫啊(自称),手速不够快啊!又被小甲逮到了。我苦心专研了数十载,开发了一个探A 【主题】,但是还缺一个app,不然你来试试😘

需求:
建立一个应用,事实汇报甲人A的方位,并传给芯不小和猫 【观察者】。
同时也是一个可扩展的,我们也要赚money嘛,只要支付一定的¥,我们就可以让更多人享受此服务


一、未使用设计模式

本着为人民服务的宗旨🤑,我义不容辞

public class Tana {private String position;public String getPosition() {return position;}public void positionChanged(){String loc=getPosition();user1.update(loc);user2.update(loc);}
}

芯不小:既然我们知道在未来会有许多的人订阅这项服务,也会有人取消,未来就不得不在代码中进行修改操作。而这就会大大增加代码的耦合度。不妨再改改😘

松耦合的强大之处
当两个对象之间松耦合,它们之间依然可以交互,但不太清除彼此的细节


二、观察者模式

1.定义

观察者模式定义了对象之间一对多的关系,这样一来,当一个对象改变状态时,它的所有依赖着都会收到并自动更新

2.组成

在这里插入图片描述

  • 抽象主题(Subject):主题是一个接口,该接口规定了具体主题需要实现的方法,比如,添加、删除观察者以及通知观察者更新数据的方法。

  • 具体主题(ConcreteSubject):具体主题是实现主题接口类的一个实例,该实例包含有可以经常发生变化的数据。具体主题需使用一个集合,比如ArrayList,存放观察者的引用,以便数据变化时通知具体观察者。

  • 抽象观察者(Observer):观察者是一个接口,该接口规定了具体观察者用来更新数据的方法。

  • 具体观察者(ConcreteObserver):具体观察者是实现观察者接口类的一个实例。具体观察者包含有可以存放具体主题引用的主题接口变量,以便具体观察者让具体主题将自己的引用添加到具体主题的集合中,使自己成为它的观察者,或让这个具体主题将自己从具体主题的集合中删除,使自己不再是它的观察者。

抽象观察者:

public interface Observer {public void update(String position);
}

具体观察者:

public class User implements Observer {// 订阅者名字private String name;public User(String name) {this.name = name;}@Overridepublic void update(String position) {System.out.println(name + "-" + position);}}

抽象主题:

public interface Subject {/*** 增加订阅者*/public void attach(Observer observer);/*** 删除订阅者*/public void detach(Observer observer);/*** 通知订阅者更新消息*/public void notify(String position);
}

具体主题:

public class SubscriptionSubject implements Subject {//储存订阅用户private List userlist = new ArrayList<>();@Overridepublic void attach(Observer observer) {userlist.add(observer);}@Overridepublic void detach(Observer observer) {userlist.remove(observer);}@Overridepublic void notify(String position) {for (Observer observer : userlist) {observer.update(position);}}
}
public class Client {public static void main(String[] args) {SubscriptionSubject subscriptionSubject=new SubscriptionSubject();//创建用户User user1=new User("猫");User user2=new User("芯不小");//订阅subscriptionSubject.attach(user1);subscriptionSubject.attach(user2);//发出消息subscriptionSubject.notify("甲A来了");}
}

三、应用场景

  • 当一个对象的数据更新时需要通知其他对象,但这个对象又不希望和被通知的那些对象形成紧耦合。

  • 当一个对象的数据更新时,这个对象需要让其他对象也各自更新自己的数据,但这个对象不知道具体有多少对象需要更新数据。


四、优缺点

  • 主题只知道观察者实现了某个接口,我们可以在任何时候增加新的观察者,同时主题的代码不用修改。当我们在其他的地方需要使用主题或观察者时,可以轻松的复用。
  • 观察者模式满足开闭原则

  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。此问题可以使用pull解决

  • 如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。

  • 观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。


终于完成啦,芯啊,这副业不就🤑,嘿嘿
芯不小:猫啊,格局,格局

某天,甲人A的办公室传来了一个声音
猫,正在摸鱼…
XXX,在浏览短视频网站…

相关内容

热门资讯

监控摄像头接入GB28181平... 流程简介将监控摄像头的视频在网站和APP中直播,要解决的几个问题是:1&...
Windows10添加群晖磁盘... 在使用群晖NAS时,我们需要通过本地映射的方式把NAS映射成本地的一块磁盘使用。 通过...
protocol buffer... 目录 目录 什么是protocol buffer 1.protobuf 1.1安装  1.2使用...
educoder数据结构与算法...                                                   ...
MySQL下载和安装(Wind... 前言:刚换了一台电脑,里面所有东西都需要重新配置,习惯了所...
MFC文件操作  MFC提供了一个文件操作的基类CFile,这个类提供了一个没有缓存的二进制格式的磁盘...
有效的括号 一、题目 给定一个只包括 '(',')','{','}'...
【Ctfer训练计划】——(三... 作者名:Demo不是emo  主页面链接:主页传送门 创作初心ÿ...
Fluent中创建监测点 1 概述某些仿真问题,需要创建监测点,用于获取空间定点的数据࿰...
带头循环双向链表来咯!!! 前言:继上文,我们了解了结构最简单的一种链表---单链表那么我们今天就来...