直观对比一下两种设计模式,左图:观察者模式;右图:策略模式。可以看到观察者模式的“下部分”就是策略模式。
观察者模式(Observer)定义:指多个对象间存在一对多的依赖关系(主题是“一”,观察者是“多”),当一个(主题)对象的状态发生改变时,所有依赖于它的(观察者)对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式。
观察者模式的优点有:
1、降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
2、目标与观察者之间建立了一套触发机制。
观察者类:
1 public interface Observer { 2 public void response(); 3 } 4 5 public class ConcreteObserverA implements Observer { 6 @Override 7 public void response() { 8 // TODO Auto-generated method stub 9 System.out.println("具体观察者1作出反应!"); 10 } 11 } 12 13 public class ConcreteObserverB implements Observer { 14 @Override 15 public void response() { 16 // TODO Auto-generated method stub 17 System.out.println("具体观察者2作出反应!"); 18 } 19 }
主题类:
1 public abstract class Subject { 2 //订阅者列表 3 protected List<Observer> observers = new ArrayList<Observer>(); 4 5 public void add(Observer oberser) { 6 observers.add(oberser); 7 } 8 9 public void remove(Observer observer) { 10 observers.remove(observer); 11 } 12 13 public abstract void notifyObserver(); 14 } 15 16 public class ConcreteSubjectA extends Subject { 17 @Override 18 public void notifyObserver() { 19 // TODO Auto-generated method stub 20 System.out.println("主题A发出通知..."); 21 System.out.println("--------------"); 22 23 for (Observer obs : observers) { 24 obs.response(); 25 } 26 } 27 } 28 29 public class ConcreteSubjectB extends Subject { 30 @Override 31 public void notifyObserver() { 32 // TODO Auto-generated method stub 33 System.out.println("主题B发出通知..."); 34 System.out.println("--------------"); 35 36 for (Observer obs : observers) { 37 obs.response(); 38 } 39 } 40 }
调用方式:
1 public class Client { 2 /* 3 * 指多个对象间存在一对多的依赖关系, 4 * 当一个对象的状态发生改变时, 5 * [所有]依赖于它的对象都得到通知并被自动更新。 6 */ 7 public static void main(String[] args) { 8 // TODO Auto-generated method stub 9 10 //主题 11 Subject subject = new ConcreteSubjectA(); 12 //观察者A,订阅主题 13 Observer observerA = new ConcreteObserverA(); 14 subject.add(observerA); 15 16 //观察者B,订阅主题 17 Observer observerB = new ConcreteObserverB(); 18 subject.add(observerB); 19 20 //主题对观察者进行通知 21 subject.notifyObserver(); 22 } 23 }
执行结果: