白话-23种设计模式14-观察者模式
【摘要】 一、白话 在网上买东西,会看到有一个价格趋势图,也会有一个按钮,写着降价通知,这样能更好的买到更便宜的东西。这就类似一种观察者模式,当一个事务的状态变更后,需要通知观察者。二、定义 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。 Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可...
一、白话
在网上买东西,会看到有一个价格趋势图,也会有一个按钮,写着降价通知,这样能更好的买到更便宜的东西。这就类似一种观察者模式,当一个事务的状态变更后,需要通知观察者。
二、定义
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增 加和删除观察者对象。
ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。
三、示例
提供两种方案:
1.自定义观察模式
// 抽象被观察者-提供观察者新增删除等
public abstract class Subject {
// 观察者
protected List<Observer> observers = new ArrayList<>();
// 新增观察者
protected void addObserver(Observer observer) {
this.observers.add(observer);
}
// 删除观察者
protected void delObserver(Observer observer) {
this.observers.remove(observer);
}
// 通知观察者
protected void notifyObservers(int price) {
for (Observer observer : observers) {
observer.update(price);
}
}
}
// 具体被观察者-产品
public class Product extends Subject {
private String name ;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
if (price < this.price) {
notifyObservers(price);
}
this.price = price;
}
public Product(String name, int price) {
this.name = name;
this.price = price;
}
}
// 抽象观察者-提供观察者需要进行的操作
public abstract class Observer {
Subject subject;
abstract void update(int price);
}
// 具体观察者-价格商城提醒
public class PriceObserver extends Observer {
// 添加观察者
public PriceObserver(Subject subject) {
this.subject = subject;
subject.addObserver(this);
}
@Override
public void update(int price) {
System.out.println("收到护肤品降价通知,目前最新价格" + price + "元");
}
}
public class ObserverApplication {
// 客户端调用
public static void main(String[] args) {
// 产品
Product product = new Product("护肤霜", 100);
// 价格观察者
PriceObserver priceObserver = new PriceObserver(product);
// 降价
System.out.println("==降价前==产品:" +product.getName()+",价格:"+product.getPrice());
product.setPrice(80);
}
}
输出结果:
==降价前==产品:护肤霜,价格:100
收到护肤品降价通知,目前最新价格80元
2.使用jdk提供的工具
主要包含两个类 java.util.Observable 抽象被观察者 java.util.Observer 抽象观察者,直接使用即可
// 具体被观察者-产品
public class Product2 extends Observable {
private String name ;
private int price;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
if (price < this.price) {
setChanged();
notifyObservers(price);
}
this.price = price;
}
public Product2(String name, int price) {
this.name = name;
this.price = price;
}
}
// 具体观察者-价格商城提醒
public class PriceObserver2 implements Observer {
@Override
public void update(Observable subject, Object params) {
if (params instanceof Integer) {
System.out.println("收到护肤品降价通知,目前最新价格" + params + "元");
}
}
}
public class Client {
// 客户端调用
public static void main(String[] args) {
// 产品
Product2 product = new Product2("护肤霜", 200);
// 价格观察者
PriceObserver2 priceObserver = new PriceObserver2();
product.addObserver(priceObserver);
System.out.println("==降价前2==产品:" +product.getName()+",价格:"+product.getPrice());
// 降价
product.setPrice(180);
}
}
输出结果:
==降价前2==产品:护肤霜,价格:200
收到护肤品降价通知,目前最新价格180元
四、总结
特点:观察者和被观察者是抽象耦合的。容易出现死循环。通知所有观察者所以浪费过多时间
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱:
cloudbbs@huaweicloud.com
- 点赞
- 收藏
- 关注作者
评论(0)