行为型模式之观察者模式
一.定义
观察者模式(Observer Pattern):定义对象间的一种一对多依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象皆得到通知并被自动更新。观察者模式又叫做发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。观察者模式是一种对象行为型模式。
二、模式结构成员构成
• Subject: 目标
• ConcreteSubject: 具体目标
• Observer: 观察者
• ConcreteObserver: 具体观察者
三.代码示例
1 /** 2 * Subject 3 * 目标 4 * 抽象主题角色类 5 */ 6 public abstract class Subject { 7 /** 8 * 用来保存注册的观察者对象 9 */ 10 private List<Observer> list = new ArrayList<Observer>(); 11 /** 12 * 注册观察者对象 13 * @param observer 观察者对象 14 */ 15 public void attach(Observer observer){ 16 17 list.add(observer); 18 System.out.println("Attached an observer"); 19 } 20 /** 21 * 删除观察者对象 22 * @param observer 观察者对象 23 */ 24 public void detach(Observer observer){ 25 26 list.remove(observer); 27 } 28 /** 29 * 通知所有注册的观察者对象 30 */ 31 public void nodifyObservers(String newState){ 32 33 for(Observer observer : list){ 34 observer.update(newState); 35 } 36 } 37 } 38 39 /** 40 * ConcreteSubject 41 * 具体目标 42 * 具体主题角色类 43 * 44 * 在运行时,这个客户端首先创建了具体主题类的实例,以及一个观察者对象。然后,它调用主题对象的attach()方法,将这个观察者对象向主题对象登记,也就是将它加入到主题对象的聚集中去。 45 这时,客户端调用主题的change()方法,改变了主题对象的内部状态。主题对象在状态发生变化时,调用超类的notifyObservers()方法,通知所有登记过的观察者对象。 46 */ 47 public class ConcreteSubject extends Subject { 48 49 private String state; 50 51 public String getState() { 52 return state; 53 } 54 55 public void change(String newState){ 56 state = newState; 57 System.out.println("主题状态为:" + state); 58 //状态发生改变,通知各个观察者 59 this.nodifyObservers(state); 60 } 61 } 62 63 /** 64 * Observer 65 * 观察者 66 * 抽象观察者角色类 67 */ 68 public interface Observer { 69 /** 70 * 更新接口 71 * @param state 更新的状态 72 */ 73 public void update(String state); 74 } 75 76 /** 77 * ConcreteObserver 78 * 具体观察者 79 * 具体观察者角色类 80 */ 81 public class ConcreteObserver implements Observer { 82 //观察者的状态 83 private String observerState; 84 85 @Override 86 public void update(String state) { 87 /** 88 * 更新观察者的状态,使其与目标的状态保持一致 89 */ 90 observerState = state; 91 System.out.println("状态为:"+observerState); 92 } 93 94 } 95 96 /** 97 * client 98 * 客户端类 99 */ 100 public class Client { 101 102 public static void main(String[] args) { 103 //创建主题对象 104 ConcreteSubject subject = new ConcreteSubject(); 105 //创建观察者对象 106 Observer observer = new ConcreteObserver(); 107 //将观察者对象登记到主题对象上 108 subject.attach(observer); 109 //改变主题对象的状态 110 subject.change("new state"); 111 } 112 113 }
四.优点和缺点分析
优点:
>观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
>观察者模式在观察目标和观察者之间建立一个抽象的耦合。
>观察者模式支持广播通信。
>观察者模式符合“开闭原则”的要求。
缺点:
>如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
>如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
五.应用场景
>一个抽象模型有两个方面,其中一个方面依赖于另一个方面。将这些方面封装在独立的对象中使它们可以各自独立地改变和复用。
>一个对象的改变将导致其他一个或多个对象也发生改变,而不知道具体有多少对象将发生改变,可以降低对象之间的耦合度。
>一个对象必须通知其他对象,而并不知道这些对象是谁。
>需要在系统中创建一个触发链,A对象的行为将影响B对象,B对象的行为将影响C对象……,可以使用观察者模式创建一种链式触发机制。
你投入得越多,就能得到越多得价值