Java设计模式——观察者模式
观察者模式(Observer Pattern)是对象出现依赖关系(一对多)时使用的,比如,当一个对象被修改时,则会自动通知它的依赖对象。观察者模式属于行为型模式。
意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
何时使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。
优点: 1、观察者和被观察者是抽象耦合的。 2、建立一套触发机制。
缺点: 1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。 2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。 3、观察者模式没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的,而仅仅只是知道观察目标发生了变化。
注意事项: 1、JAVA 中已经有了对观察者模式的支持类。 2、避免循环引用。 3、如果顺序执行,某一观察者错误会导致系统卡壳,一般采用异步方式。
类图:
代码:
一、建立Subject被观察对象,其中保存了一个放置观察者的Arraylist,在状态更新时(函数),触发一个提醒所有观察者更新的函数
1 public class Subject { 2 public ArrayList<Observer> observers = new ArrayList<Observer>(); 3 public int state; 4 public int i = 0; 5 6 public int getState(){ 7 return state; 8 } 9 10 public void attach(Observer observer){ 11 observers.add(observer); 12 } 13 14 public void setState(int state){ 15 this.state = state; 16 notifyAllObserver(); 17 } 18 19 public void notifyAllObserver(){ 20 for (Observer observer : observers) { 21 observer.update(); 22 } 23 } 24 }
二、建立观察者抽象类
1 public abstract class Observer { 2 protected Subject subject; 3 public abstract void update(); 4 }
三、建立观察者实体类,构造函数中要把自己加入到被观察者的集合中去
1 public class BinaryObserver extends Observer { 2 3 4 public BinaryObserver(Subject subject){ 5 this.subject = subject; 6 this.subject.attach(this); 7 } 8 9 @Override 10 public void update() { 11 System.out.println("Binary String: " + Integer.toBinaryString( subject.getState() )); 12 } 13 14 }
1 public class OctalObserver extends Observer { 2 3 public OctalObserver(Subject subject){ 4 this.subject = subject; 5 this.subject.attach(this); 6 7 } 8 9 @Override 10 public void update() { 11 System.out.println( "Octal String: " + Integer.toOctalString( subject.getState() ) ); 12 13 } 14 15 }
1 public class HexaObserver extends Observer { 2 3 public HexaObserver(Subject subject){ 4 this.subject = subject; 5 this.subject.attach(this); 6 7 } 8 9 @Override 10 public void update() { 11 System.out.println( "Hex String: " + Integer.toHexString( subject.getState() ).toUpperCase() ); 12 } 13 14 }
四、测试
1 public class ObserverPatternDemo { 2 3 public static void main(String[] args) { 4 Subject subject = new Subject(); 5 6 new BinaryObserver(subject); 7 new OctalObserver(subject); 8 new HexaObserver(subject); 9 10 System.out.println("改变设值为15"); 11 subject.setState(15); 12 System.out.println("改变设值为20"); 13 subject.setState(20); 14 } 15 16 }