根据 GoF 的定义,观察者模式定义了对象之间的一对多依赖关系,这样当一个对象改变状态时,它的所有依赖对象都会得到通知并自动更新。它也称为发布-订阅模式。
在观察者模式中,有许多观察者(订阅者对象)正在观察一个特定的主题(发布者对象)。观察者将自己注册到一个主题,以便在该主题内部发生更改时收到通知。
观察者对象可以在任何时候从主题注册或注销。它有助于使对象松耦合。
如上所述,当您设计一个系统时,多个实体对某个特定第二实体对象的任何可能更新感兴趣,我们可以使用观察者模式。
观察者模式
流程很容易理解。应用程序创建具体的主题对象。所有具体的观察者都注册自己,以便在主题状态的任何进一步更新中得到通知。
一旦主题的状态发生变化,主题就会通知所有注册的观察者,观察者可以访问更新后的状态并采取相应的行动。
观察者模式时序图
关注者可以随时关注或取消关注另一个人。一旦取消关注,此人将不会收到来自主题的通知。
观察者模式架构
观察者模式有四个参与者。
在下面的示例中,我创建了一个 Subject
类型的消息发布者和三个 Observer
类型的订阅者。发布者会定期向所有订阅或附加的观察者发布消息,他们会将更新后的消息打印到控制台。
主题和具体主题
public interface Subject { public void attach(Observer o); public void detach(Observer o); public void notifyUpdate(Message m); }
import java.util.ArrayList; import java.util.List; public class MessagePublisher implements Subject { private List<Observer> observers = new ArrayList<>(); @Override public void attach(Observer o) { observers.add(o); } @Override public void detach(Observer o) { observers.remove(o); } @Override public void notifyUpdate(Message m) { for(Observer o: observers) { o.update(m); } } }
观察者和具体观察者
public interface Observer { public void update(Message m); }
public class MessageSubscriberOne implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberOne :: " + m.getMessageContent()); } }
public class MessageSubscriberTwo implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberTwo :: " + m.getMessageContent()); } }
public class MessageSubscriberThree implements Observer { @Override public void update(Message m) { System.out.println("MessageSubscriberThree :: " + m.getMessageContent()); } }
状态对象
这必须是一个不可变< /a> 对象,这样任何类都不能错误地修改它的内容。
public class Message { final String messageContent; public Message (String m) { this.messageContent = m; } public String getMessageContent() { return messageContent; } }
现在测试发布者和订阅者之间的通信。
public class Main { public static void main(String[] args) { MessageSubscriberOne s1 = new MessageSubscriberOne(); MessageSubscriberTwo s2 = new MessageSubscriberTwo(); MessageSubscriberThree s3 = new MessageSubscriberThree(); MessagePublisher p = new MessagePublisher(); p.attach(s1); p.attach(s2); p.notifyUpdate(new Message("First Message")); //s1 and s2 will receive the update p.detach(s1); p.attach(s3); p.notifyUpdate(new Message("Second Message")); //s2 and s3 will receive the update } }
程序输出。
MessageSubscriberOne :: First Message MessageSubscriberTwo :: First Message MessageSubscriberTwo :: Second Message MessageSubscriberThree :: Second Message
观察者的性质和功能可以不同,但它们都必须实现一个通用的 Observer
接口,该接口主题支持注册和注销。
可以。我们可以随时添加或删除观察者。
在观察者模式中,所有已注册的处理程序对象同时获得通知并同时处理更新。
但在责任链模式中,链中的处理程序对象被一个接一个地通知,这个过程一直持续到一个对象完全处理通知为止。
主题和观察者构成了一个松散耦合的系统。他们不需要明确地了解对方。我们可以随时独立添加或删除观察者。
相关 Java 类:
地址:https://www.cundage.com/article/observer-design-pattern.html