原文请看这里敖丙观察者模式。
小白不保证完全正确
观察者模式
目的
当一个对象的状态发生改变时,已经登记的其他对象能够观察到这一改变从而作出自己相对应的改变。通过这种方式来达到减少依赖关系,解耦合的作用。
当一个对象A自身属性发生变化时,其他对象可以观察到这种变化并做出反应。
它定义了对象之间一对多的依赖关系,使得每当一个对象的状态发生改变时,其相关依赖对象都能够收到通知并自动更新。
角色
- Subject(主题): 主要由类实现的可观察的接口,通知观察者使用attach方法,以及取消观察的detach方法。 被观察者
- ConcreteSubject(具体主题): 是一个实现主题接口的类,处理观察者的变化
- Observe(观察者): 观察者是一个由对象水岸的接口,根据主题中的更改而进行更新。
Subject(主题)就是被观察者
举例
微信朋友圈:你就是一个主题或者说被观察者,此时你的朋友就是观察者,当你发布一条动态你的朋友(观察者)都能够看到,并能够进行点赞或者留言。
上课:老师就是一个主题,下面的学生就是观察者
代码实现
Subject(被观察者)接口
public interface Subject {
// 添加订阅关系
void attach(Observer observer);
// 移除订阅关系
void detach(Observer observer);
// 通知订阅者
void notifyObservers(String message);
}
Subject(被观察者)接口实现类
public class ConcreteSubject implements Subject {
// 订阅者容器
private List<Observer> observers = new ArrayList<Observer>();
@Override
public void attach(Observer observer) {
// 添加订阅关系
observers.add(observer);
}
@Override
public void detach(Observer observer) {
// 移除订阅关系
observers.remove(observer);
}
@Override
public void notifyObservers(String message) {
// 通知订阅者们
for (Observer observer : observers) {
observer.update(message);
}
}
}
注意这段代码,使用订阅容器List<Observer> observers
维护订阅关系,notifyObservers
函数实现(被)观察
// 订阅者容器
private List<Observer> observers = new ArrayList<Observer>();
@Override
public void notifyObservers(String message) {
// 通知订阅者们
for (Observer observer : observers) {
observer.update(message);
}
}
观察者接口
public interface Observer {
// 处理业务逻辑
void update(String message);
}
观察者接口实现类
public class FriendOneObserver implements Observer {
@Override
public void update(String message) {
// 模拟处理业务逻辑
System.out.println("FriendOne 知道了你发动态了" + message);
}
}
测试代码
public class test {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
// 这里假设是添加好友
subject.attach(new FriendOneObserver());
FriendTwoObserver twoObserver = new FriendTwoObserver();
subject.attach(twoObserver);
// 发送朋友圈动态
subject.notifyObservers("第一个朋友圈消息");
// 输出结果:FriendOne 知道了你发动态了第一个朋友圈消息
// FriendTwo 知道了你发动态了第一个朋友圈消息
// 这里发现 twoObserver 是个推荐卖茶叶的,删除好友
subject.detach(twoObserver);
subject.notifyObservers("第二个朋友圈消息");
// 输出结果:FriendOne 知道了你发动态了第二个朋友圈消息
}
}
应用场景
- 在GUI编程中,观察者模式被广泛应用于处理UI控件的事件,如按钮点击事件、鼠标移动事件等。UI控件作为被观察者(Subject),而事件监听器则充当观察者(Observer)角色,它们之间是一种loosely coupled的关系。
- 在MVC架构中,模型(Model)扮演被观察者的角色,而视图(View)则是观察者。当模型的数据发生变化时,它会通知所有注册的视图进行相应的更新。‘’
观察者模式为对象间的状态通知和事件驱动编程提供了一种松耦合的解决方案