浅谈Java设计模式——观察者模式(Observer)
一、概述
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。观察者模式定义了对象之间的一对多依赖关系,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并且自动更新。在这里,发生改变的对象称之为观察目标,而被通知的对象称之为观察者。一个观察目标可以对应多个观察者,而且这些观察者之间没有相互联系,所以么可以根据需要增加和删除观察者,使得系统更易于扩展。所以观察者提供了一种对象设计,让主题和观察者之间以松耦合的方式结合。
二、使用场景
1.当一个抽象模型有两个方面,其中一个方面依赖于另一方面。 将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
2.当对一个对象的改变需要同时改变其它对象,而不知道具体有多少对象有待改变。
3.当一个对象必须通知其它对象,而它又不能假定其它对象是谁。
三、参与者
1.Subject (目标)目标知道它的观察者。可以有任意多个观察者观察同一个目标。 提供注册和删除观察者对象的接口。
2.Observer (观察者)为那些在目标发生改变时需获得通知的对象定义一个更新接口。
3.ConcreteSubject (具体目标)将有关状态存入各ConcreteObserver对象。 当它的状态发生改变时,向它的各个观察者发出通知。
4.ConcreteObserver (具体观察者)维护一个指向ConcreteSubject对象的引用。 存储有关状态,这些状态应与目标的状态保持一致。 实现 Observer的更新接口以使自身状态与目标的状态保持一致
四、类图
五、示例代码
1.Subject
/**
* Subject
* @author zhipeng_Tong
*/
public abstract class Subject {
private ArrayList<Observer> observers = new ArrayList<>();
// 添加观察者
public void add(Observer observer) {
observers.add(observer);
}
// 移除观察者
public void remove(Observer observer) {
observers.remove(observer);
}
// 通知
public void toNotify() {
for (Observer observer : observers)
observer.update();
}
}
2.Observer
/**
* Observer
* @author zhipeng_Tong
*/
public interface Observer {
void update();
}
3.ConcreteSubject
/**
* ConcreteSubject
* @author zhipeng_Tong
*/
public class Boss extends Subject {
private String subjectState; // 保存状态信息
public String getSubjectState() {
return subjectState;
}
public void setSubjectState(String subjectState) {
this.subjectState = subjectState;
}
}
4.ConcreteObserver
/**
* ConcreteObserver
* @author zhipeng_Tong
*/
public class StockObserver implements Observer {
private String name; // 名称
private String observerState; // 状态
private Boss subject; // 通知者
public StockObserver(String name, Boss subject) {
this.name = name;
this.subject = subject;
}
@Override
public void update() {
observerState = subject.getSubjectState();
System.out.println(String.format("%s - %s 关闭股票软件,继续工作。", observerState, name));
}
}
5.测试代码
public class Client {
public static void main(String[] args) {
Boss boss = new Boss();
boss.add(new StockObserver("李传华", boss));
boss.add(new StockObserver("周大海", boss));
boss.setSubjectState("老板回来了");
boss.toNotify();
}
}
运行结果:
老板回来了 - 李传华 关闭股票软件,继续工作。
老板回来了 - 周大海 关闭股票软件,继续工作。