观察者模式(Observer)
1.意图
定义对象间的一种一对多的依赖关系 ,当一个对象的状态发生改变时 , 所有依赖于它的对象都得到通知并被自动更新。
将一个系统分割成一系列相互协作的类有一个常见的副作用:需要维护相关对象间的一致性。我们不希望为了维持一致性而使各类紧密耦合,因为这样降低了它们的可重用性。
在以下任一情况下可以使用观察者模式 :
• 当一个抽象模型有两个方面 , 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
• 当对一个对象的改变需要同时改变其它对象 , 而不知道具体有多少对象有待改变。
• 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之 , 你不希望这些对象是紧密耦合的。
2.特点
• Subject(目标)
— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
— 提供注册和删除观察者对象的接口。
• Observer(观察者)
— 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
• ConcreteSubject(具体目标)
— 将有关状态存入各 ConcreterObserver对象。
— 当它的状态发生改变时 , 向它的各个观察者发出通知。
• ConcreterObserver(具体观察者)
— 维护一个指向ConcreteSubject对象的引用。
— 存储有关状态,这些状态应与目标的状态保持一致。
— 实现Observer的更新接口以使自身状态与目标的状态保持一致。
• 当ConcreteSubject发生任何可能导致其观察者与其本身状态不一致的改变时,它将通知它的各个观察者。
• 在得到一个具体目标的改变通知后 , ConcreteObserver 对象可向目标对象查询信息。ConcreteObserver使用这些信息以使它的状态与目标对象的状态一致。
3.UML类图
4.代码
/**
* • Subject(目标)
— 目标知道它的观察者。可以有任意多个观察者观察同一个目标。
— 提供注册和删除观察者对象的接口。
*/
public interface Subject {
//添加观察者
void addObserver(Observer observer);
//删除观察者
void deleteObserver(Observer observer);
//通知观察者
void notifyObservers(String message);
}
/**
* • ConcreteSubject(具体目标)
— 将有关状态存入各 ConcreterObserver对象。
— 当它的状态发生改变时 , 向它的各个观察者发出通知。
*/
public class ConcreteSubject implements Subject{
List<Observer> list = new ArrayList<Observer>();
@Override
public void addObserver(Observer observer) {
list.add(observer);
}
@Override
public void deleteObserver(Observer observer) {
list.remove(observer);
}
@Override
public void notifyObservers(String message) {
for(Observer o : list){
o.update(message);
}
}
}
/**
* • Observer(观察者)
— 为那些在目标发生改变时需获得通知的对象定义一个更新接口。
*/
public interface Observer {
//当目标状态改变时,会将一个String类型字符传入该方法的参数,每个观察者都需要实现该方法
void update(String info);
}
/**
* • ConcreterObserver(具体观察者)
— 维护一个指向ConcreteSubject对象的引用。
— 存储有关状态,这些状态应与目标的状态保持一致。
— 实现Observer的更新接口以使自身状态与目标的状态保持一致。
*/
public class ConcreteObserver implements Observer{
private String info;
@Override
public void update(String info) {
this.info = info;
System.out.println(this.info);
}
}
/**
* Created by lyy on 18-3-29.
*/
public class ObserverTest {
public static void main(String[] args) {
Observer observer1 = new ConcreteObserver();
Observer observer2 = new ConcreteObserver();
Observer observer3 = new ConcreteObserver();
Observer observer4 = new ConcreteObserver();
Subject subject = new ConcreteSubject();
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.addObserver(observer3);
subject.addObserver(observer4);
subject.notifyObservers("发送通知");
subject.deleteObserver(observer4);
subject.notifyObservers("再次发送通知");
}
}