设计模式之观察者模式
观察者模式定义了一种一对多的的依赖,当被监听者发生改变或被观察者需要通知订阅者(或观察者)时,观察者会收到通知。观察者模式有以下几部分组成。
1) 抽象目标角色(Subject):目标角色知道它的观察者,可以有任意多个观察者观察同一个目标。并且提供注册和删除观察者对象的接口。目标角色往往由抽象类或者接口来实现。
2) 抽象观察者角色(Observer):为那些在目标发生改变时需要获得通知的对象定义一个更新接口。抽象观察者角色主要由抽象类或者接口来实现。
3) 具体目标角色(Concrete Subject):将有关状态存入各个 Concrete Observer 对象。当它的状态发生改变时 , 向它的各个观察者发出通知。
4) 具体观察者角色(Concrete Observer):存储有关状态,这些状态应与目标的状态保持一致。实现 Observer 的更新接口以使自身状态与目标的状态保持一致。在本角色内也可以维护一个指向 Concrete Subject 对象的引用。
在java中提供了observable的类和observer的接口来实现观察者模式。
例子如下:
1 package com.cnblogs.ipolaris.observer.test; 2 3 import java.util.Observable; 4 /** 5 * 被观察者 6 * @author iPolaris 7 * 8 */ 9 public class People extends Observable { 10 private String name ; 11 private int age ; 12 public String getName() { 13 return name ; 14 } 15 public void setName(String name) { 16 this.name = name; 17 this.setChanged(); 18 this.notifyObservers(); 19 } 20 public int getAge() { 21 return age ; 22 } 23 public void setAge(int age) { 24 this.age = age; 25 this.setChanged(); 26 this.notifyObservers(); 27 } 28 29 30 } 31 32 33 34 35 36 package com.cnblogs.ipolaris.observer.test; 37 38 import java.util.Observable; 39 import java.util.Observer; 40 /** 41 * 观察者,当被观察者发生变化时,会调用update方法 42 * @author iPolaris 43 * 44 */ 45 public class MyObserver implements Observer { 46 47 @Override 48 public void update(Observable o, Object arg) { 49 System.out.println("被观察者发生了变化!"); 50 } 51 52 } 53 54 55 package com.cnblogs.ipolaris.observer.test; 56 57 public class Test { 58 59 /** 60 * @param args 61 */ 62 public static void main(String[] args) { 63 People people = new People(); 64 //添加观察者 65 people.addObserver( new MyObserver()); 66 people.setAge(20); 67 68 } 69 70 }
Observer和Observerable是用java提供的,我们自己来写个简单的写个Observer和Observerable来模仿其实现原理:
1 package com.cnblogs.ipolaris.observer.test; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public class IObservable { 7 private List<IObserver> observers = new ArrayList<IObserver>(); 8 private boolean changed = false; 9 public void addObserver(IObserver observer){ 10 observers .add(observer); 11 } 12 public void setChanged(){ 13 this .changed = true; 14 } 15 public void notifyObservers(){ 16 if (changed ){ 17 for (IObserver observer:observers ){ 18 observer.update( this , null ); 19 } 20 } 21 } 22 } 23 24 25 26 package com.cnblogs.ipolaris.observer.test; 27 28 29 public interface IObserver { 30 public void update(IObservable observable, Object data ); 31 } 32 33 package com.cnblogs.ipolaris.observer.test; 34 35 public class Count extends IObservable { 36 public int num ; 37 public Count(int num){ 38 this .num = num; 39 } 40 public void chang(){ 41 this .num --; 42 this .setChanged(); 43 this .notifyObservers(); 44 } 45 } 46 47 package com.cnblogs.ipolaris.observer.test; 48 49 public class ITest { 50 51 public static void main(String[] args) { 52 Count count = new Count(20); 53 count.addObserver( new MyIObserver()); 54 count.chang(); 55 56 } 57 58 }
被观察者要有一个容器来存放观察者(当添加/注册观察者时,其实是向此容器里添加对象),当changed的值为true(即被观察者的状态发生改变时),调用一个通知方法,通知容器内的观察者,观察者接到消息后做相应的处理,这样实现了一种简单的监听。