模式动机:建立一种对象与对象之间的依赖关系
UML图:
实例一:猫、狗与老鼠
•假设猫是老鼠和狗的观察目标,老鼠和狗是观察者,猫叫老鼠跑,狗也跟着叫,使用观察者模式描述该过程。
接口
import java.util.ArrayList; public abstract class Subject { ArrayList observers = new ArrayList(); public abstract void attach(Observer observer); public abstract void detach(Observer observer); public abstract void cry(); }
观察者接口:
public interface Observer { public void response(); }
实例化 猫
package designpatten.observer; public class Cat extends Subject{ @Override public void attach(Observer observer) { // TODO Auto-generated method stub observers.add(observer); } @Override public void detach(Observer observer) { // TODO Auto-generated method stub observers.remove(observer); } @Override public void cry() { // TODO Auto-generated method stub System.out.println("猫叫!"); System.out.println("---------------------------"); for(Object obs:observers){ ((Observer)obs).response(); } } }
实例化 狗和老鼠
public class Dog implements Observer { @Override public void response() { // TODO Auto-generated method stub System.out.println("------------------狗在叫-----------------"); } }
package designpatten.observer; public class Mouse implements Observer { @Override public void response() { // TODO Auto-generated method stub System.out.println("------------------老鼠在跑----------------"); } }
client
package designpatten.observer; public class Client { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub Subject subject = new Cat(); Observer obs1 = new Dog(); Observer obs2 = new Mouse(); subject.attach(obs1); subject.attach(obs2); subject.cry(); } }
ü观察者模式的优点
•观察者模式可以实现表示层和数据逻辑层的分离,并定义了稳定的消息更新传递机制,抽象了更新接口,使得可以有各种各样不同的表示层作为具体观察者角色。
•观察者模式在观察目标和观察者之间建立一个抽象的耦合。
•观察者模式支持广播通信。
•观察者模式符合“开闭原则”的要求。
ü观察者模式的缺点
•如果一个观察目标对象有很多直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
•如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。
•观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。