主页传送门: 传送
观察者模式(Observer Pattern)是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。其定义如下:
Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
即:定义对象之间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新。
其通用类图如下:
观察者模式所涉及的角色有:
抽象主题(Subject)角色:
抽象主题角色把所有对观察者对象的引用保存在一个聚集(比如ArrayList对象)里,每个主题都可以有任何数量的观察者。抽象主题提供一个接口,可以增加和删除观察者对象,抽象主题角色又叫做抽象被观察者(Observable)角色。
具体主题(ConcreteSubject)角色:
将有关状态存入具体观察者对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知。具体主题角色又叫做具体被观察者(Concrete Observable)角色。
抽象观察者(Observer)角色:
为所有的具体观察者定义一个接口,在得到主题的通知时更新自己,这个接口叫做更新接口。
具体观察者(ConcreteObserver)角色:
存储与主题的状态自恰的状态。具体观察者角色实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态 像协调。如果需要,具体观察者角色可以保持一个指向具体主题对象的引用。
下面举一个具体实例,假设上班时间有一部分同事在看股票,一部分同事在看NBA,这时老板回来了,前台通知了部分同事老板回来了,这些同事及时关闭了网页没被发现,而没被通知到的同事被抓了个现行,被老板亲自“通知”关闭网页
public interface Subject {
//增加
public void attach(Observer observer);
//删除
public void detach(Observer observer);
//通知
public void notifyObservers();
//状态
public void setAction(String action);
public String getAction();
}
public abstract class Observer {
protected String name;
protected Subject subject;
public Observer(String name, Subject subject) {
this.name = name;
this.subject = subject;
}
public abstract void update();
}
public class Secretary implements Subject {
//同事列表
private List<Observer> observers = new LinkedList<>();
private String action;
//添加
@Override
public void attach(Observer observer) {
observers.add(observer);
}
//删除
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
//通知
@Override
public void notifyObservers() {
for(Observer observer : observers) {
observer.update();
}
}
//前台状态
@Override
public String getAction() {
return action;
}
@Override
public void setAction(String action) {
this.action = action;
}
}
public class StockObserver extends Observer {
public StockObserver(String name, Subject subject) {
super(name, subject);
}
@Override
public void update() {
System.out.println(subject.getAction() + "\n" + name + "关闭股票行情,继续工作");
}
}
public class Client {
public static void main(String[] args) {
//前台为通知者
Secretary secretary = new Secretary();
StockObserver observer = new StockObserver("adam", secretary);
NBAObserver observer2 = new NBAObserver("tom", secretary);
//前台通知
secretary.attach(observer);
secretary.attach(observer2);
//adam没被前台通知到,所以被老板抓了个现行
secretary.detach(observer);
//老板回来了
secretary.setAction("小心!Boss回来了!");
//发通知
secretary.notifyObservers();
}
public class Client {
public static void main(String[] args) {
//老板为通知者
Boss boss = new Boss();
StockObserver observer = new StockObserver("adam", boss);
NBAObserver observer2 = new NBAObserver("tom", boss);
//老板通知
boss.attach(observer);
boss.attach(observer2);
//tom没被老板通知到,所以不用挨骂
boss.detach(observer2);
//老板回来了
boss.setAction("咳咳,我大Boss回来了!");
//发通知
boss.notifyObservers();
}
}
观察者模式的优点包括:
然而,观察者模式也存在一些缺点:
观察者模式适用于以下场景:
除了以上场景,观察者模式还适用于任何需要实现一对多依赖关系的场景。
观察者模式是一种设计模式,用于在对象之间建立一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。这种模式在许多领域都有广泛的应用,如GUI开发、事件处理、状态管理等。
总的来说,观察者模式在某些情况下可以非常有用,但是也需要根据实际需求来考虑其适用性。在实际开发中,我们可以使用观察者模式来实现新闻推送、消息广播等需求,以提高代码的可维护性和可扩展性。
如果喜欢的话,欢迎 关注 点赞 评论 收藏 一起讨论
你的支持就是我✍️创作的动力!