何为观察者模式
观察者模式定义对象之间的一对多依赖,这样一来,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。
观察者模式的类图如下所示。
示例
比如我自己有一个公众号,公众号每隔一段时间会推送消息(发布者),然后订阅公众号的用户(观察者)可以看到订阅者的消息。
创建一个消息类,包括标题,日期,简要内容。
public class Message {
private String title;
private Date date;
private String content;
}
定义 Subject 接口,有注册订阅者,取消注册订阅者和发布消息。
public interface Subject {
/**
* 注册订阅者
*
* @param observer
*/
void attach(Observer observer);
/**
* 取消注册订阅者
*
* @param observer
*/
void detach(Observer observer);
/**
* 通知
*/
void notifyObserver();
}
定义观察者接口,主要接收来自 Subject 发布的消息。
public interface Observer {
void update(Message message);
}
实现 Subject 接口。
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class MyWxSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private Message message = new Message();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObserver() {
observers.forEach(observer -> observer.update(message));
}
public void setMessage(String title, String content) {
message.setDate(new Date());
message.setTitle(title);
message.setContent(content);
// 发布消息,通知订阅者(观察者)
notifyObserver();
}
}
实现观察者接口。
public class Observer1 implements Observer {
private String username;
public Observer1(String username) {
this.username = username;
}
/**
* 接收来自订阅者的消息
*
* @param message 消息实体类
*/
@Override
public void update(Message message) {
System.out.println(username + ",收到的消息如下");
System.out.println(message);
}
}
测试一下
public class ObserverTest {
public static void main(String[] args) {
MyWxSubject myWxSubject = new MyWxSubject();
Observer1 zhangsan = new Observer1("zhangsan");
Observer1 lisi = new Observer1("lisi");
Observer1 wangwu = new Observer1("wangwu");
// 注册消息
myWxSubject.attach(zhangsan);
myWxSubject.attach(lisi);
myWxSubject.attach(wangwu);
myWxSubject.setMessage("观察模式", "观察者模式定义对象之间的一对多依赖,这样一来,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。");
System.out.println("======================================");
// 李四不订阅了
myWxSubject.detach(lisi);
myWxSubject.setMessage("单例模式", "确保类只有一个实例,并提供一个全局的访问点");
}
}
运行一下
zhangsan,收到的消息如下
Message(title=观察模式, date=Wed Mar 15 17:11:28 CST 2023, content=观察者模式定义对象之间的一对多依赖,这样一来,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。)
lisi,收到的消息如下
Message(title=观察模式, date=Wed Mar 15 17:11:28 CST 2023, content=观察者模式定义对象之间的一对多依赖,这样一来,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。)
wangwu,收到的消息如下
Message(title=观察模式, date=Wed Mar 15 17:11:28 CST 2023, content=观察者模式定义对象之间的一对多依赖,这样一来,当一个对象的状态发生改变时,它的所有依赖者都会收到通知并自动更新。)
======================================
zhangsan,收到的消息如下
Message(title=单例模式, date=Wed Mar 15 17:11:28 CST 2023, content=确保类只有一个实例,并提供一个全局的访问点)
wangwu,收到的消息如下
Message(title=单例模式, date=Wed Mar 15 17:11:28 CST 2023, content=确保类只有一个实例,并提供一个全局的访问点)
请勿发布违反中国大陆地区法律的言论,请勿人身攻击、谩骂、侮辱和煽动式的语言。