设计模式学习笔记之观察者模式
观察者模式
    定义了对象之间的一对多依赖,这样一来,当一个对象状态改变时,它的所有依赖者都会收到通知并自动更新。
    观察者模式中,分为推和拉两种模式。
    推模式,即主题对象向观察者对象推送状态值,不管观察者对象是否需要,并且推送全部数据或者部分数据。
    拉模式,即主题对象通知观察者对象状态值已改变,观察者根据自己需要决定是否主动到主体对象中获取详细信息。
    两种模式的比较
1、推模型是假定主题对象知道观察者需要的数据;而拉模型是主题对象不知道观察者具体需要什么数据,没有办法的情况下,干脆把自身传递给观察者,让观察者自己去按需要取值。
2、推模型可能会使得观察者对象难以复用,因为观察者的update()方法是按需要定义的参数,可能无法兼顾没有考虑到的使用情况。这就意味着出现新情况的时候,就可能提供新的update()方法,或者是干脆重新实现观察者;而拉模型就不会造成这样的情况,因为拉模型下,update()方法的参数是主题对象本身,这基本上是主题对象能传递的最大数据集合了,基本上可以适应各种情况的需要。
    说明:
    1、观察者模式将观察者和主题(被观察者)的对象分离开,实现了两者的松耦合。提高了应用程序的可维护性和重用性;
    2、JAVA API 内置有观察者模式。位于java.util包,包含有最基本的Observer接口与Observable类,分别对应观察者和主题;
    3、主题仅需要把实时的状态值更新给观察者即可,而不需要知道观察者怎样处理数据或者其他细节。
    场景:
    1、对于一个对象的状态值需要实时更新到其他任何几个对象。如气象站检测的天气数据,要实时更新给气象网站的布告板。
| /**  * 主题类接口。  * 用来定义注册观察者、移除观察者、通知更新等方法  * @author xiabaike  */ public interface Subject {     /**      * 注册观察者      * */     public void registerObserver(Observer o);     /**      * 移除观察者      * */     public void removeObserver(Observer o);     /**      * 当状态改变时,调用此方法,通知所有观察者      * */     public void notifyObservers(); } | 
| /**  * 观察者类接口。  * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者。  * @author xiabaike  * */ public interface Observer {     /**      * 当主题状态发生改变时,主题会把这些状态值当做方法的参数,传送给观察者      * 所有观察者都必须实现此方法,以实现观察者接口      * */     public void  update(float temp, float humidity, float pressure); } | 
| /**  * 展示。在布告板上显示内容   * */ public interface DisplayElement {     /**      * 当布告板需要显示时,调用此方法      * */     public void display(); } | 
| /**  * 天气数据类。产生更新状态值,并通知布告板观察者  * */ public class WeatherData implements Subject{     // 用来存放所有的观察者     private List<Observer> observerList;     private float tempPerature;     private float humidity;     private float pressure;     public WeatherData() {         observerList = new ArrayList<Observer>();     }     public void registerObserver(Observer o) {         observerList.add(o);     }     public void removeObserver(Observer o) {         if(observerList.contains(o)) {             observerList.remove(o);         }     }     public void notifyObservers() {         for(int i = 0; i < observerList.size(); i++) {             observerList.get(i).update(tempPerature, humidity, pressure);         }     }     /**      * 当从气象站得到更新观测值时,通知观察者      * */     public void setMeasurements(float temperature, float humidity, float pressure) {         this.tempPerature = temperature;         this.humidity = humidity;         this.pressure = pressure;         notifyObservers();     } } | 
| /**  * 具体布告板实现类。获取状态值,并展示  * */ public class CurrentConditionsDisplay implements Observer, DisplayElement{     private float tempPerature;     private float humidity;     private float pressure;     private Subject subject;     public CurrentConditionsDisplay(Subject subject) {         this.subject = subject;         this.subject.registerObserver(this);     }     public void update(float temp, float humidity, float pressure) {         this.tempPerature = temp;         this.humidity = humidity;         this.pressure = pressure;         display();     }     public void display() {         System.out.println("Current conditions: " + tempPerature +", "+ humidity +", "+ pressure);     } } | 
| /**  * 主类,模拟气象站产生检测数据,并更新给布告板  * */ public class WeatherStation {     public static void main(String[] args) {         WeatherData subject = new WeatherData();         CurrentConditionsDisplay observer = new CurrentConditionsDisplay(subject);         subject.setMeasurements(1, 2, 3);     } } | 
参考资料:《Head First 设计模式》
 
                    
                     
                    
                 
                    
                
 
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号