模式定义:
观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。
在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。
观察者模式又称为发布-订阅模式
模式结构:
模式实现:
public class ObserverMode {
/**
* 观察者接口
*/
interface Observer {
public void update(float num);
}
/**
* 被观察者接口
*/
interface Subject {
public void registerObserver(Observer observer);
public void removeObserver(Observer observer);
public void notifyObserver();
}
/**
* 某一股 股票类
*/
class Stock implements Subject {
/**
* 股票值
*/
private float num;
/**
* 所有查看该股票的软件结合
*/
private List<Observer> observers;
public Stock() {
observers = new ArrayList<>();
}
@Override
public void registerObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
int i = observers.indexOf(observer);
if (i >= 0) {
observers.remove(i);
}
}
@Override
public void notifyObserver() {
for (int i = 0; i < observers.size(); i++) {
observers.get(i).update(num);
}
}
/**
* 股票发生改变
*
* @param num
*/
public void change(float num) {
this.num = num;
notifyObserver();
}
}
/**
* 软件a
*/
class SoftwareA implements Observer {
public Subject subject;
public SoftwareA(Subject subject) {
this.subject = subject;
}
@Override
public void update(float num) {
System.out.println(this.getClass().getSimpleName() + " receive this change : num is " + num);
}
}
/**
* 软件b
*/
class SoftwareB implements Observer {
public Subject subject;
public SoftwareB(Subject subject) {
this.subject = subject;
}
@Override
public void update(float num) {
System.out.println(this.getClass().getSimpleName() + " receive this change : num is " + num);
}
}
/**
* 测试类
*/
@Test
public void observerTest() {
//初始化 股票类及观察者类
Stock subject = new Stock();
Observer observer1 = new SoftwareA(subject);
Observer observer2 = new SoftwareB(subject);
//注册并发送通知(正常来说,都是在 观察者中调用 注册及解绑操作)
subject.registerObserver(observer1);
subject.registerObserver(observer2);
subject.change(22.22f);
//解注册并发送通知
subject.removeObserver(observer1);
subject.change(33.33f);
}
}
模式优点:
1、当两个对象之间送耦合,他们依然可以交互,但是不太清楚彼此的细节。观察者模式提供了一种对象设计,让主题和观察者之间送耦合。主题所知道只是一个具体的观察者列表,每一个具体观察者都符合一个抽象观察者的接口。主题并不认识任何一个具体的观察者,它只知道他们都有一个共同的接口
2、观察者模式支持“广播通信”。主题会向所有的观察者发出通知。
3、观察者模式符合“开闭原则”的要求
模式缺点:
1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进 行循环调用,可能导致系统崩溃
3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化
适用场景:
1、一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用
2、一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度
注意点:
1、因观察者与被观察者之间存在双向依赖(或双向组合),开发是要注意及时解绑,防止内存泄漏