观察者模式(Observer)

      观察者模式:定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并更新。

主题和观察者定义了一对多的关系,观察者依赖于主题。当主题对象的状态发生改变时,观察者就会被通知。根据通知观察者进行相关操作。

 一、 涉及角色主题接口观察者接口具体主题具体观察者。

     

    

优点:主题是真正拥有数据的对象,观察者是主题的依赖者,在数据变化跟新时这样比多个对象控制同一份数据,可以更干净的OO设计。

缺点:并不是所有的观察者都需要这份数据,有可能只需要其中的一部分,却接收了一堆数据。(JDK中的观察这模式,提供了支持,支持以个getter方法的主动获取数据)

二、代码实例

     (1)抽象观察者角色

1 public interface Observer {
2     /**
3      * <p>观察者对象更新自己的信息</p>
4      * @author maxianming 2016-1-11 下午2:11:44
5      * @param Message
6      */
7     public void update(String Message);
8 }

 

     (2)抽象主题角色

  

 1 public interface Subject {
 2     /**
 3      * <p>主题对象中注册一个观察者</p>
 4      * @author maxianming 2016-1-11 下午2:09:17
 5      * @param observer
 6      */
 7     public void registerObserver(Observer observer);
 8     /**
 9      * <p>主题对象中删除一个观察者</p>
10      * @author maxianming 2016-1-11 下午2:09:53
11      * @param observer
12      */
13     public void removeObserver(Observer observer);
14     /**
15      * <p>主题对象改变通知所有的观察者对象</p>
16      * @author maxianming 2016-1-11 下午2:11:05
17      */
18     public void notifyObservers();
19 }

 

     (3)具体观察者角色

 1 public class ConcreteObserver implements Observer {
 2     private Subject subject;
 3     
 4     public ConcreteObserver(Subject subject){
 5         this.subject = subject;
 6         subject.registerObserver(this);
 7     }
 8     
 9     @Override
10     public void update(String message) {
11          System.out.println("具体观察者得到 【主题对象的信息】为:" + message);        
12     }
13     
14 }

 

     (4)具体主题角色

 

 1 public class ConcreteSubject implements Subject {
 2     private ArrayList<Observer> observers;
 3     private String message;
 4     
 5     public ConcreteSubject(){
 6         this.observers = new ArrayList<Observer>();
 7     }
 8     @Override
 9     public void registerObserver(Observer observer) {
10         this.observers.add(observer);
11     }
12     
13     @Override
14     public void removeObserver(Observer observer) {
15         boolean hasObserver = this.observers.contains(observer);
16         if(hasObserver){
17             this.observers.remove(observer);
18         }
19     }
20     
21     @Override
22     public void notifyObservers() {
23         for (int i = 0; i < observers.size(); i++) {
24             Observer observer = observers.get(i);
25             if(observer != null){
26                 observer.update(this.message);
27             }
28             
29         }
30     }
31     
32     public void setData(String message){
33         this.message = message;
34         //状态改变,通知观察者
35         this.notifyObservers();
36     }
37 }

 

     (5)客户端

 

 1 public class Client {
 2     public static void main(String[] args) {
 3         //1、主题对象
 4         ConcreteSubject subject = new ConcreteSubject();
 5         //2、观察者对象
 6         Observer observer = new ConcreteObserver(subject);
 7         //3、主题对象信息改变
 8         subject.setData("213123213");
 9         
10         //4、删除观察者对象
11         subject.removeObserver(observer);
12         //5、主题对象信息gaibian
13         subject.setData("3456178");
14     }
15 }

 

三、JDK中观察者模式

    JDK对观察者模式提供了支持。主题类Observable,具体主题类可以继承JDK中实现类Observable类。具体观察者可以实现JDK中的观察者接口Observer接口

    主题通知观察者:继承JDKObservable的主题接口,通知观察者对象步骤。

    (1)先调用Observable中的setChanged()方法。标记状态已经改变

    (2)再调用notifyObservers()或notifyObservers(arg)(带参数方法可以推送指定的参数)。

    

 

posted @ 2015-12-29 14:33  浮生若云  阅读(590)  评论(0编辑  收藏  举报