设计模式第二集——观察者模式(Observer)

  观察者模式,就像订报纸杂志。出版社(主题Subject)有新的报纸出版就会通知读者(观察者 Observer),当读者不想看报纸的时候,取消订阅就不会再受到新送来的报纸。这就是一种典型的观察者模式。

  观察者模式:在对象之间定义一对多的依赖,这样当一个对象改变状态,依赖它的对象都会受到通知并自动更新。

  观察者类图:

  Subject是主题接口,对象使用这个接口注册为观察者也可以把自己从观察者中删除。ConcreteSubject是实现主题的接口,除了注册和撤销方法之外还有notifyOvservers(),用于在状态改变是更新当前所有的观察者。

  Observer观察者接口,这个接口只有update()一个方法,当主题状态改变时它被调用。

观察者模式提供了一种对象设计,让主题和观察者之间松耦合。对于主题和观察者之间唯一依赖的东西就是实现Observer接口的对象列表,可以随时增删观察者。

  举个例子:气象观测版。一个WeatherData对象有关于温度、湿度、气压等方面的信息,将信息发送给布告板,布告板有很多种。下面就是这个例子的类图,为布告板建立一个共同的接口。

代码:

首先建立三个接口:

 1 package com.Subject;
 2 
 3 import com.Observer.Observer;
 4 
 5 public interface Subject {
 6     public void registerObserver(Observer o);
 7     public void removeObserver(Observer o);
 8     //当主题状态改变时,这个方法会被调用,以通知所有的观察者
 9     public void notifyObservers();
10 
11 }
12 
13 package com.Observer;
14 
15 public interface Observer {
16     //所有的观察者都需要实现update的方法
17     //当气象观测值发生改变的时候,主题会把这些值作为参数传给观察者
18     public void update(float temp,float humidity,float pressure);
19 }
20 
21 package com.Display;
22 
23 public interface DisplayElement {
24     //DisplayElement接口只包含一个display方法。当广告版需要显示时调用此方法
25     public void display();
26 
27 }

WeatherData实现主题的接口

 1 package com.Subject;
 2 
 3 import java.util.ArrayList;
 4 
 5 import com.Observer.Observer;
 6 
 7 public class WeatherData implements Subject{
 8     private ArrayList observers;//这个就是观察者的列表
 9     private float temperature;
10     private float humidity;
11     private float pressure;
12     
13     public WeatherData(){
14         observers=new ArrayList();//观察者的list在构造函数中建立
15     }
16     
17     public void registerObserver(Observer o) {
18         observers.add(o);//注册就是把观察者加到列表中
19         
20     }
21     
22     public void removeObserver(Observer o) {
23         int i=observers.indexOf(o);
24         if(i>=0){
25             observers.remove(i);
26         }        
27     }
28 
29     @Override
30     public void notifyObservers() {
31         //把状态告诉每一个观察者去更新数据
32         for(int i=0;i<observers.size();i++){
33             Observer observer=(Observer) observers.get(i);
34             observer.update(temperature, humidity, pressure);
35         }        
36     }
37     
38     public void measurementsChanged(){
39         //当从外界比如气象站得到更新观测值是,通知观察者
40         notifyObservers();
41     }
42     public void setMeasurements(float temperature,float humidity,float pressure){
43         this.humidity=humidity;
44         this.pressure=pressure;
45         this.temperature=temperature;
46         measurementsChanged();
47     }
48 }

布告板:

 1 package com.Display;
 2 
 3 import com.Observer.Observer;
 4 import com.Subject.Subject;
 5 
 6 public class CurrentConditionsDisplay implements Observer,DisplayElement{
 7     private float temperature;
 8     private float humidity;
 9     private Subject weatherData;
10     
11     
12     public CurrentConditionsDisplay(Subject weatherData) {
13         //在构造器时注册observer
14         this.weatherData = weatherData;
15         weatherData.registerObserver(this);
16     }
17 
18     @Override
19     public void display() {
20         System.out.println("Current conditions:"+temperature+"F degree and"+humidity+"% humidity");
21         
22     }
23 
24     @Override
25     public void update(float temp, float humidity, float pressure) {
26         this.temperature=temp;
27         this.humidity=humidity;
28         display();        
29     }
30 
31 }

测试:

package com.test;

import com.Display.CurrentConditionsDisplay;
import com.Subject.WeatherData;

public class WeatherStation {
    public static void main(String args[]){
        //首先建立一个WeahterData对象(主题)
        WeatherData weatherdata=new WeatherData();
        //一个现实版
        CurrentConditionsDisplay currentDisplay=new CurrentConditionsDisplay(weatherdata);
        //调用setMeasurements方法设立现在的weather值
        weatherdata.setMeasurements(80, 65, 30.4f);
    }

}

这样一个观察者模式,就做好了!

需要注意的是,在java.util包中包含了Observer包,然后任何observable对象的addOvserver()方法,不想当观察者时,调用deleteObserver()方法就可以了。但是最好自己写观察者,因为java API的Observable是一个类,必须要设计一个类继承它。如果某个类想同时具有Observable类和另一个超类的行为,就没有办法了(因为java不支持多重继承)

转载于:https://www.cnblogs.com/doublesong/archive/2012/07/29/2614042.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式是一种常见的设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。在这个模式中,被观察者对象通常称为主题(Subject),而观察者对象通常称为观察者(Observer)。 下面我们就以一个简单的天气预报系统为例来介绍观察者模式的使用。 首先,我们需要定义一个主题接口(Subject),它包含了添加、删除和通知观察者的方法: ```java public interface Subject { public void registerObserver(Observer o); public void removeObserver(Observer o); public void notifyObservers(); } ``` 然后,我们需要定义一个观察者接口(Observer),它包含了更新数据的方法: ```java public interface Observer { public void update(float temp, float humidity, float pressure); } ``` 接下来,我们需要定义一个具体的主题类(WeatherData),它实现了主题接口,并包含了一个列表来存储观察者对象,以及当前的温度、湿度和气压等数据: ```java import java.util.ArrayList; public class WeatherData implements Subject { private ArrayList<Observer> observers; private float temperature; private float humidity; private float pressure; public WeatherData() { observers = new ArrayList<Observer>(); } public void registerObserver(Observer o) { observers.add(o); } public void removeObserver(Observer o) { int i = observers.indexOf(o); if (i >= 0) { observers.remove(i); } } public void notifyObservers() { for (int i = 0; i < observers.size(); i++) { Observer observer = (Observer)observers.get(i); observer.update(temperature, humidity, pressure); } } public void measurementsChanged() { notifyObservers(); } public void setMeasurements(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; this.pressure = pressure; measurementsChanged(); } // other WeatherData methods here } ``` 最后,我们需要定义一个具体的观察者类(CurrentConditionsDisplay),它实现了观察者接口,并在更新数据时打印出当前的温度、湿度和气压等信息: ```java public class CurrentConditionsDisplay implements Observer { private float temperature; private float humidity; private Subject weatherData; public CurrentConditionsDisplay(Subject weatherData) { this.weatherData = weatherData; weatherData.registerObserver(this); } public void update(float temperature, float humidity, float pressure) { this.temperature = temperature; this.humidity = humidity; display(); } public void display() { System.out.println("Current conditions: " + temperature + "F degrees and " + humidity + "% humidity"); } } ``` 现在,我们可以创建一个天气预报系统,它包含了一个主题对象和一个观察者对象,并通过调用主题对象的方法来更新数据和通知观察者: ```java public class WeatherStation { public static void main(String[] args) { WeatherData weatherData = new WeatherData(); CurrentConditionsDisplay currentDisplay = new CurrentConditionsDisplay(weatherData); weatherData.setMeasurements(80, 65, 30.4f); weatherData.setMeasurements(82, 70, 29.2f); weatherData.setMeasurements(78, 90, 29.2f); } } ``` 以上就是一个简单的观察者模式的例子,它可以让我们更好地理解和应用这个常见的设计模式

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值