`

观察者模式

 
阅读更多

From : http://canann.iteye.com/blog/1814653

 

 

12.3.3  Java中的观察者模式

       估计有些朋友在看前面的内容的时候,心里就嘀咕上了,Java里面不是已经有了观察者模式的部分实现吗,为何还要全部自己从头做呢?

       主要是为了让大家更好的理解观察者模式本身,而不用受Java语言实现的限制。

       好了,下面就来看看如何利用Java中已有的功能来实现观察者模式。在java.util包里面有一个类Observable,它实现了大部分我们需要的目标的功能;还有一个接口Observer,它里面定义了update的方法,就是观察者的接口。

       因此,利用Java中已有的功能来实现观察者模式非常简单,跟前面完全由自己来实现观察者模式相比有如下改变:

  • 不需要再定义观察者和目标的接口了,JDK帮忙定义了
  • 具体的目标实现里面不需要再维护观察者的注册信息了,这个在Java中的Observable类里面,已经帮忙实现好了
  • 触发通知的方式有一点变化,要先调用setChanged方法,这个是Java为了帮助实现更精确的触发控制而提供的功能
  • 具体观察者的实现里面,update方法其实能同时支持推模型和拉模型,这个是Java在定义的时候,就已经考虑进去了

好了,说了这么多,还是看看例子会比较直观。

(1)新的目标的实现,不再需要自己来实现Subject定义,在具体实现的时候,也不是继承Subject了,而是改成继承Java中定义的Observable,示例代码如下:

/**

 * 报纸对象,具体的目标实现

 */

public class NewsPaper extends  java.util.Observable   {

    /**

     * 报纸的具体内容

     */

    private String content;

    /**

     * 获取报纸的具体内容

     * @return 报纸的具体内容

     */

    public String getContent() {

       return content;

    }

    /**

     * 示意,设置报纸的具体内容,相当于要出版报纸了

     * @param content 报纸的具体内容

     */

    public void setContent(String content) {

       this.content = content;

       //内容有了,说明又出新报纸了,那就通知所有的读者

       //注意在用Java中的Observer模式的时候,下面这句话不可少

       this.setChanged();

       //然后主动通知,这里用的是推的方式

       this.notifyObservers(this.content);

       //如果用拉的方式,这么调用

       //this.notifyObservers();

    }

}

(2)再看看新的观察者的实现,不是实现自己定义的观察者接口,而是实现由Java提供的Observer接口,示例代码如下:

/**

 * 真正的读者,为了简单就描述一下姓名

 */

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());

 

 

 

 

 

 

 


    }

}

(3)客户端使用

客户端跟前面的写法没有太大改变,主要在注册阅读者的时候,调用的方法跟以前不一样了,示例代码如下:

public class Client {

    public static void main(String[] args) {

       //创建一个报纸,作为被观察者

       NewsPaper subject = new NewsPaper();

       //创建阅读者,也就是观察者

       Reader reader1 = new Reader();

       reader1.setName("张三");

 

       Reader reader2 = new Reader();

       reader2.setName("李四");

 

       Reader reader3 = new Reader();

       reader3.setName("王五");

 

       //注册阅读者

       subject.addObserver(reader1);

       subject.addObserver(reader2);

       subject.addObserver(reader3);

 

       //要出报纸啦

       subject.setContent("本期内容是观察者模式");

    }

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics