假设您有两种类型的对象:客户和商店。客户对当前缺货的产品非常感兴趣。客户可以每天访问商店或致电商店检查产品可用性。但是,该产品仍然不可用,并且这些访问/电话中的大多数都是徒劳的。
观察者设计模式
具有某种有趣状态的对象通常称为主体,但由于它会通知其他对象有关其状态的更改,因此我们将其称为发布者。订阅者是跟踪发布者状态变化的对象。
观察者建议向发布者类添加订阅机制,以便单个对象可以订阅或取消订阅来自该发布者的事件流。发布者现在将通过调用其对象的通知方法在发生重要事件时通知其订阅者。
UML 类图
实施步骤
- 您的业务逻辑应分为两部分。独立于其他代码的核心功能应该是发布者,而其余的将成为订阅者类。
- 定义订阅者接口。它至少应该声明一个更新方法。
- 定义发布者接口并描述添加和删除订阅者对象的方法。发布者必须仅通过订阅者接口与订阅者交互。
- 决定将实际订阅列表放在哪里以及如何实现订阅方法。因为此代码对于所有类型的发布者通常都是相同的,所以将其放置在直接从发布者接口派生的抽象类中是显而易见的。具体的发布者扩展了这个类,继承了订阅功能。
- 创建具体的发布者。发布者必须在其中发生重要事件时通知其所有订阅者。
- 创建实现更新通知方法的具体订阅者类。大多数订阅者需要一些上下文信息。它可以作为通知方法的参数传递。
- 客户端必须创建所有必要的订阅者并将它们注册到适当的发布者。
源代码实现
NumberSubscriber 是通知订阅者的接口。它通常由一个更新方法组成。该方法可能有几个参数,使发布者能够随更新发送一些事件详细信息。
packagecom.learncsdesign;publicinterfaceNumberSubscriber{publicvoidupdate(NumberPublisher numGen);
}
NumberPublisher 向其他对象发送感兴趣的事件。 这些事件在发布者更改其状态或执行某些行为时发生。 Publisher 中的订阅基础结构允许新订阅者加入和现有订阅者离开。
每当发生新事件时,发布者都会遍历订阅列表,并为每个订阅者对象调用订阅者接口中声明的通知方法。
packagecom.learncsdesign;importjava.util.LinkedList;importjava.util.List;importjava.util.Random;publicclassNumberPublisher{privateList subscribers =newLinkedList<>();privateintnumber;publicintgetNumber(){returnnumber;
}publicvoidsubscribe(NumberSubscriber s){
subscribers.add(s);
}publicvoidunsubscribe(NumberSubscriber s){
subscribers.remove(s);
}publicvoidnotifySubscribers(){for(NumberSubscriber s: subscribers){
s.update(this);
}
}publicvoidnumberGenerator(){
Random rand =newRandom();
number = rand.nextInt(100);
System.out.println("Number generated : "+ number);
notifySubscribers();
}
}
HexNumberSubscriber 和 OctalNumberSubscriber 执行一些操作以响应发布者的通知。 NumberPublisher 可以作为参数传递,允许订阅者直接获取任何需要的数据。
packagecom.learncsdesign;publicclassHexNumberSubscriberimplementsNumberSubscriber{@Overridepublicvoidupdate(NumberPublisher numGen){
System.out.println("Number in Hex format : 0x"+ Integer.toHexString(numGen.getNumber()));
}
}
packagecom.learncsdesign;publicclassOctalNumberSubscriberimplementsNumberSubscriber{@Overridepublicvoidupdate(NumberPublisher numGen){
System.out.println("Number in octal format : 0"+ Integer.toOctalString(numGen.getNumber()));
}
}
ObserverClient 分别创建订阅者和发布者对象,然后为发布者更新注册订阅者。
packagecom.learncsdesign;publicclassObserverClient{publicstaticvoidmain(String[] args){
NumberSubscriber hexSubscriber =newHexNumber();
NumberSubscriber octSubscriber =newOctalNumber();
NumberPublisher pub =newNumberPublisher();
pub.subscribe(hexSubscriber);
pub.subscribe(octSubscriber);
pub.numberGenerator();
}
}
//OutputNumber generated :23Number in Hex format :0x17Number in octal format :027
何时应用观察者设计模式
- 观察者模式用于改变一个对象的状态可能需要改变其他对象,并且对象的集合是不知道提前或动态变化的。
- 当您的应用程序中的某些对象必须在有限的时间或特定情况下观察其他对象时,请使用此模式。
观察者设计模式的优点
- 可以在不更改发布者代码的情况下添加新的订阅者类。
- 对象之间的关系可以在运行时建立。
如果你喜欢这篇文章,你知道该怎么做
原文链接:https://www.w1ym.com/82535/,转载请注明出处~~~
评论0