《大话设计模式》——观察者模式(订阅--发布模式)
观察者模式结构图:
从上图中可以看到观察者模式需要4个角色:
1.Observer:抽象观察者。
2.ConcreteObserver:具体观察者。
3.Subject:抽象通知者。
4.ConcreteSubject:具体通知者。
这里我们用上班玩手机来举例:有几个同事每天在公司的状态为“玩手机”,然后为了不给老板发现,安排了一个靠近大门的同事当他们的通知者,当老板走入大门的时候,这个同事就要马上通知他们,他们会更新状态为“工作”。假如这个同事没有及时通知他们,那么通知者就会变成老板,老板当场抓获他们的状态为“玩手机”,同时还要当场批评。
下面我们通过代码来进行实现:
1.定义抽象观察者同事Observer,里面只有一个方法update用来更新状态:这里定义接口的意义在于遵循“开放--封闭原则”,如果有新的偷偷看电影的同事,也可以实现接口,保证对观察者对象的内部一致性。
public interface Observer { void update(String state); }
2.定义具体的观察者同事ConcreteObserver:
public class ConcreteObserver implements Observer { private String state = "玩手机"; //默认在玩手机 @Override public void update(String state) { //由坐在靠窗位置的同事进行通知,通知后马上修改状态。 this.state = state; } }
3.定义抽象通知者同事:这里接口的定义同样是为了满足"开放—封闭原则",因为通知者有可能是靠窗的同事,也可能是被老板给抓了现场。
public interface Subject { void add(Observer observer); //添加通知的同事 void remove(Observer observer); //移除通知的同事 void notice(String notice); //通知同事 }
4.定义具体的通知者同事:这里只定义了通知者同事,没有定义通知者老板,老板类似,只不过会多一个扣除工资的操作。
public class ConcreteSubject implements Subject { private List<Observer> list = new ArrayList<>(); @Override public void add(Observer observer) { list.add(observer); } @Override public void remove(Observer observer) { list.remove(observer); } @Override public void notice(String notice) { for (Observer observer : list) { observer.update("工作!"); } } }
5.客户端:实际流程开始了
public class Main8 { public static void main(String[] args) { Subject subject1 = new ConcreteSubject(); //通知者同事 Observer observer1 = new ConcreteObserver(); //观察者同事1 Observer observer2 = new ConcreteObserver(); //观察者同事2 Observer observer3 = new ConcreteObserver(); //观察者同事3 //将同事添加到通知对象里面来 subject1.add(observer1); subject1.add(observer2); subject1.add(observer3); // 老板来了,赶紧通知工作! subject1.notice("工作!"); } }
特点:
将一个复杂系统分成几个小模块后,需要在这几个模块中保持一致性,但是又不能让他们进行紧耦合。此时可以通过观察者模式,又称订阅—发布模式,令这几个模块都订阅某一事件,当事件发生后,通知模块会对订阅了这一事件的模块分别进行通知,以让他们保持一致性。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)