码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式学习——观察者模式(Observer Pattern)

时间:2015-09-16 08:36:11      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:

0. 前言

  观察者模式在许多地方都能够用到,特别是作为MVC模式的一部分,在MVC中,模型(M):存放数据,视图(V):显示数据。当模型中的数据发生改变时,视图会得到通知,这是典型的观察者模式。

1. 定义

  观察者模式:定义了一对多的关系,一个对象作为主题,它维护了一系列的依赖对象,当主题的状态发生改变时,会自动地通知依赖对象(通常通过调用依赖对象的方法来实现)。

  官方定义:wiki

2. 应用

  这里通过《Head first 设计模式》中的例子来实现观察者模式。这里有一个气象数据和公布栏,当气象数据发生改变时,会通知公布栏,使其更新数据。

 技术分享

 

源码:

主题Subject接口:

1 package ObserverPattern;
2 
3 public interface Subject {
4     public void registerObserver( Observer observer );
5     public void removeObserver( Observer observer );
6     public void notifyObservers();
7 }

观察者Observer接口

1 package ObserverPattern;
2 
3 public interface Observer {
4     public void update(Object obj);
5 }

 

气象数据实现:

 1 package ObserverPattern;
 2 
 3 import java.util.ArrayList;
 4 import java.util.Iterator;
 5 
 6 public class WeatherData implements Subject {
 7 
 8     private ArrayList<Observer> observers = null;
 9     private double temperature;
10     private double humidity;
11     private double pressure;
12     
13     public WeatherData(  )
14     {
15         observers = new ArrayList<>();
16     }
17     
18     public double getTemperature() {
19         return temperature;
20     }
21 
22     public double getHumidity() {
23         return humidity;
24     }
25 
26     public double getPressure() {
27         return pressure;
28     }
29 
30     public void SetWeather( double temperature, double humidity, double pressure )
31     {
32         this.temperature = temperature;
33         this.humidity = humidity;
34         this.pressure = pressure;
35         mesurementsChanged();
36     }
37     
38     public void mesurementsChanged()
39     {
40         notifyObservers();
41     }
42     
43     @Override
44     public void registerObserver(Observer observer) {
45         observers.add(observer);
46     }
47 
48     @Override
49     public void removeObserver(Observer observer) {
50         observers.remove(observer);
51     }
52 
53     @Override
54     public void notifyObservers() {
55         
56         for ( Iterator<Observer> iterator = observers.iterator();  iterator.hasNext(); ) {
57             Observer observer = (Observer) iterator.next();
58             observer.update(this);
59         }
60     }
61 
62 }

显示接口:

1 package ObserverPattern;
2 
3 public interface DisplayBoard {
4     public void display();
5 }

公布栏实现:

 1 package ObserverPattern;
 2 
 3 public class CurrentWeatherBoard implements Observer, DisplayBoard {
 4 
 5     private double temperature;
 6     
 7     public CurrentWeatherBoard( Subject subject ) {
 8         subject.registerObserver(this);
 9     }
10     
11     @Override
12     public void update(Object obj) {
13         if ( obj instanceof WeatherData ) {
14             WeatherData weatherData = (WeatherData)obj;
15             this.temperature = weatherData.getTemperature();
16             display();
17         }
18     }
19 
20     @Override
21     public void display() {
22         System.out.println(this.getClass().getName() + ":" +  this.temperature);
23     }
24 
25 }

 

3. JDK中Observable类分析

  在JDK中提供了Observable类以及Observer接口方便实现观察者模式,但是这里的主题是Observable是一个类,需要通过继承来实现,所以很大的限制了它的使用。

  Observable类的添加观察者方法,通过synchronized实现同步,其Observable内部维护着一个Vector容器,用于存放观察者对象。  

1  public synchronized void addObserver(Observer o) {
2         if (o == null)
3             throw new NullPointerException();
4         if (!obs.contains(o)) {
5             obs.addElement(o);
6         }
7     }

   

  通知函数,这里会判断一个标识,所以在调用通知时需要先调用 setChanged 方法,然后将其观察者保存到一个数组中,这里会有一个问题,即当调用删除一个观察者的时候,如果正在调用notifyObservers时,依然会通知到被删除的观察者。对于添加来说也是一样的,会错过这一次的通知。

 1 public void notifyObservers(Object arg) {
 2 
 3         Object[] arrLocal;
 4 
 5         synchronized (this) {
 6             if (!changed)
 7                 return;
 8             arrLocal = obs.toArray();
 9             clearChanged();
10         }
11 
12         for (int i = arrLocal.length-1; i>=0; i--)
13             ((Observer)arrLocal[i]).update(this, arg);
14     }

 

设计模式学习——观察者模式(Observer Pattern)

标签:

原文地址:http://www.cnblogs.com/jabnih/p/4811216.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!