设计模式_10:观察者模式
来源:互联网 发布:mac 印象笔记插件下载 编辑:程序博客网 时间:2024/05/22 10:58
观察者(Observer)模式又称为发布订阅模式(Publish/Subscribe),如果一个对象改变时需要通知其他对象,那么就可以用观察者模式解决。
一个简单的例子:顾客订阅了卖家,以后卖家有什么新消息(优惠活动、打折什么的)就可以找到并通知给顾客了:
import java.util.ArrayList;import java.util.List;public class Main { public static void main(String[] args) { Seller seller = new Seller(); Customer tony = new Customer("Tony", seller); Customer lisa = new Customer("Lisa", seller); seller.attach(tony); seller.attach(lisa); seller.setNotifyText("薯条、薯片半价"); seller.send_notify(); }}//卖家(消息通知者)class Seller { private String notifyText; private List<Customer> customerList = new ArrayList<>(); //添加顾客(消息订阅者) public void attach(Customer customer){ customerList.add(customer); } //通知顾客最新消息 public void send_notify(){ for (Customer customer : customerList){ customer.update(); } } public String getNotifyText() { return notifyText; } public void setNotifyText(String notifyText) { this.notifyText = notifyText; }}//顾客(消息订阅者)class Customer { private String name; private Seller seller; public Customer(String name, Seller seller) { this.name = name; this.seller = seller; } //得到通知时所采取的行动(这里只是简单地输出一下通知内容) public void update(){ System.out.println(name + "收到通知:" + seller.getNotifyText()); }}
Tony收到通知:薯条、薯片半价Lisa收到通知:薯条、薯片半价
基本的观察者模式是这样了,不过现在卖家和顾客相互紧紧的耦合在一起了,也就是说顾客依赖于具体的卖家,卖家也需要知道具体的顾客,不符合依赖倒转原则,并且如果老板(另一种订阅者)也需要订阅卖家的消息,那么原来卖家的代码就需要修改了,这样也不符合开放-闭合原则,所以需要改良 解耦:
import java.util.ArrayList;import java.util.List;public class Main { public static void main(String[] args) { Seller seller = new Seller(); Customer tony = new Customer("Tony", seller); Customer lisa = new Customer("Lisa", seller); seller.attach(tony); seller.attach(lisa); seller.setNotifyText("薯条、薯片半价"); seller.send_notify(); }}//卖家(消息通知者)class Seller { private String notifyText; //把Customer改成Observer private List<Observer> observerList = new ArrayList<>(); //添加顾客(消息订阅者) public void attach(Observer observer){ observerList.add(observer); } //去除顾客(以后不再通知该顾客) public void detach(Observer observer){ observerList.remove(observer); } //通知顾客最新消息 public void send_notify(){ for (Observer observer : observerList){ observer.update(); } } public String getNotifyText() { return notifyText; } public void setNotifyText(String notifyText) { this.notifyText = notifyText; }}//抽象出一个观察者类(抽象消息订阅者)abstract class Observer { protected String name; protected Seller seller; public Observer(String name, Seller seller) { this.name = name; this.seller = seller; } abstract void update();}//顾客(具体消息订阅者)class Customer extends Observer{ public Customer(String name, Seller seller) { super(name, seller); } //得到通知时所采取的行动(这里只是简单地输出一下通知内容) @Override public void update(){ System.out.println(name + "收到通知:" + seller.getNotifyText()); }}
通过依赖抽象类Observer,Seller类就不需要知道具体订阅消息的是谁了,但现在顾客依赖的仍然是具体的卖家,所以还需要改改:
import java.util.ArrayList;import java.util.List;public class Main { public static void main(String[] args) { Subject seller = new Seller(); Observer tony = new Customer("Tony", seller); Observer lisa = new Customer("Lisa", seller); seller.attach(tony); seller.attach(lisa); seller.setSubjectState("薯条、薯片半价"); seller.send_notify(); }}//把消息发布者抽象成接口interface Subject { void attach(Observer observer); void detach(Observer observer); void send_notify(); String getSubjectState(); void setSubjectState(String subjectState);}//卖家(消息通知者)class Seller implements Subject{ private String notifyText; //把Customer改成Observer private List<Observer> observerList = new ArrayList<>(); //添加顾客(消息订阅者) @Override public void attach(Observer observer){ observerList.add(observer); } //去除顾客(以后不再通知该顾客) @Override public void detach(Observer observer){ observerList.remove(observer); } //通知顾客最新消息 @Override public void send_notify(){ for (Observer observer : observerList){ observer.update(); } } @Override public String getSubjectState() { return this.notifyText; } @Override public void setSubjectState(String subjectState) { this.notifyText = subjectState; }}//抽象出一个观察者类(抽象消息订阅者)abstract class Observer { protected String name; protected Subject subject; public Observer(String name, Subject subject) { this.name = name; this.subject = subject; } abstract void update();}//顾客(具体消息订阅者)class Customer extends Observer{ public Customer(String name, Subject subject) { super(name, subject); } //得到通知时所采取的行动(这里只是简单地输出一下通知内容) @Override public void update(){ System.out.println(name + "收到通知:" + subject.getSubjectState()); }}
最后,我把消息发布者也抽象成接口了
阅读全文
1 0
- 设计模式_10:观察者模式
- 单例模式(设计模式_10)
- 模式设计:观察者模式
- 设计模式-----观察者模式
- 设计模式-观察者模式
- 设计模式--观察者模式
- 设计模式:观察者模式
- 设计模式-----观察者模式
- 设计模式:观察者模式
- 设计模式-观察者模式
- 设计模式 观察者模式
- 设计模式-观察者模式
- 设计模式-【观察者模式】
- 设计模式-观察者模式
- 设计模式 -- 观察者模式
- 设计模式-观察者模式
- 【设计模式】观察者模式
- 设计模式- 观察者模式
- 【zookeeper读书笔记】第一章--分布式架构
- 安装,配置kafka
- 284. Peeking Iterator
- 地图行政区域标注问题
- FFmpeg解码流程
- 设计模式_10:观察者模式
- mysql练习语句
- 从键盘传入多个字符串到程序中,并将它们按逆序输出在屏幕上
- Fork/Join框架
- 图片相关操作
- 【笔记】《WebGL编程指南》学习-第6章着色器语言(1-基础)
- ACM输入外挂
- 学习 square 日历框架 android-times-square
- 加一 -LintCode