观察者模式(Observer)

1、本质:触发联动

2、定义:

    定义对象间的一种一对多的依赖关系。当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新

    例如:报社的报纸出版时,通知所有的订阅者

3、示意图:

    

4、特点:

    1、目标与观察值之间的关系      --一对多关系

    2、单向依赖             --观察者依赖于目标,而目标不依赖于观察者

5、注意:

    1、要在状态维护完成后触发通知,否则容易导致观察者与目标对象的状态不一致

    2、小心出现相互观察,比如A观察C,C观察A。这样可能会导致死循环

6、推模型和拉模型

    1、推模型

        目标对象主动向观察者推送目标的详细信息,不管观察者是否需要。

        推送的信息通常是目标对象的全部或者部分数据,相当于广播通信

    2、拉模型

        目标对象通知观察者的时候,只传递少量信息

        如果观察者需要更具体的信息,主动到目标对象中获取

        目标对象一般把自身作为参数传递给观察者

 

7、Java中的观察者模式

    1、不需要定义观察者和目标的接口,JDK已经定义了

    2、目标对象中不再需要维护观察者的注册信息,在Java中的Observable类里面已经实现了

    3、触发通知的方式改变,先调用setChanged方法

    4、观察者里面,update方法同时支持推模型和拉模型

8、Java中的观察者模式使用示例:

  1、目标类

 1 public class NewsPaper extends java.util.Observable{
 2     private String content;
 3     public String getContent(){
 4         return content;
 5     }
 6     
 7     /*
 8     * 更新报纸内容,相当于出版报纸
 9     */
10     public void setContent(String content){
11         this.content = content;
12         
13         //这句话必不可少
14         this.setChanged();
15         //推方式
16         this.notifyObservers(this.content);
17         //拉方式
18         //this.notifyObservers();
19     }
20 }

  2、观察者类

public class Reader implements java.util.Observer{
    private String name;
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name = name;
    }
    
    public void update(Observable o, Object obj){
        //推方式
        System.out.println(name+"收到报纸了,内容是"+obj);
        //拉方式
        System.out.println(name+"收到报纸了,内容是"+((NewsPaper)o).getContent());
    }
}

  备注:Java实现观察者模式默认使用拉模型。      --如果使用推模型,两种方式都能获取到值

  3、客户端

public class Client{
    public static void main(String[] args){
        NewsPaper subject = new NewsPaper();
        
        Reader r1 = new Reader();
        r1.setName("张三");
        Reader r2 = new Reader();
        r2.setName("李四");
        Reader r3 = new Reader();
        r3.setName("王五");
        
        subject.addObserver(r1);
        subject.addObserver(r2);
        subject.addObserver(r3);
        
        subject.setContent("本期内容是观察者模式");
    }
}

 

9、优点:

    1、实现了观察者和目标之间的抽象耦合

    2、实现了动态联动

    3、支持广播通信

10、缺点:

    可能会引起无谓的操作

posted @ 2014-04-16 11:24  无名十四  阅读(232)  评论(0)    收藏  举报