设计模式笔记——观察者模式

来源:互联网 发布:循环cpu调度算法 编辑:程序博客网 时间:2024/06/10 05:05

     应用场景举例:观察者模式就类似于日常生活中订阅报纸,当你订阅了报纸后,报社每次出版新的报纸,都会送到你家。

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

     实现:在Java中观察者模式有两个实现方法,一种是自定义实现,另一种是Java内置观察者。下面分别分析下两种实现方法。

设计原则:1、为了交互对象之间的松耦合设计而努力。

一、自定义实现

    1:结构


2:示例代码

接口:

<span style="font-size:18px;">/** * 主题接口 */public interface Subject{    /**     * registerObserver()与removeObserver()这两个方法都需要一个观察     * 者作为变量,该观察者是用来注册或被删除的。     */    public void registerObserver(Observer o);    public void removeObserver(Observer o);    /**     * 当主题状态改变时,这个方法会被调用,以通知所有的观察者。     */    public void notifyObservers();}/** * 观察者接口 */public interface Observer{    /**     * 所有的观察者都必须实现update()方法,以实现观察者接口     * @param testFlag     */    public void update(int testFlag);}public interface DisplayElement{    //显示方法    public void display();}</span>

类实现:

<span style="font-size:18px;">/** * 实现主题接口 */public class NewsPaperOffice implements Subject     //实现Subject接口{    private ArrayList observers;    private int testFlag;    public NewsPaperOffice()    {        observers=new ArrayList();    }    @Override    public void registerObserver(Observer o) {        observers.add(o);    }    @Override    public void removeObserver(Observer o) {        int i=observers.indexOf(o);        if(i>=0)        {            observers.remove(i);        }    }    @Override    public void notifyObservers()    {        for(int i=0;i<observers.size();++i)        {            Observer observer=(Observer)observers.get(i);            observer.update(testFlag);        }    }    /**     * 当testFlag更新时通知观察者     */    public void testFlagChanged()    {        notifyObservers();    }    public void setTestFlag(int testFlag)    {        this.testFlag=testFlag;    }}/** * 显示类实现Observer接口,所以可以从NewsPaperOffice中获得数据; * 所有显示类必须实现DisplayElement接口。 */public class CurrentCoditionsDisplay implements Observer,DisplayElement{    private int testFlag;    private Subject newsPaperOffice;    /**     * 构造器需要NewsPaperOffice对象作为注册之用     * @param newsPaperOffice     */    public CurrentCoditionsDisplay(Subject newsPaperOffice)    {        this.newsPaperOffice=newsPaperOffice;        newsPaperOffice.registerObserver(this);    }    @Override    public void display() {        System.out.println("CurrentCodition testFlag="+testFlag);    }    @Override    public void update(int testFlag) {        this.testFlag=testFlag;        display();    }}public class ObserveMode{    public static void main(String[] args)    {        NewsPaperOffice newsPaperOffice=new NewsPaperOffice();        CurrentCoditionsDisplay currentDisplay=new CurrentCoditionsDisplay(newsPaperOffice);        newsPaperOffice.setTestFlag(2);        newsPaperOffice.setTestFlag(10);    }}</span>


二、Java内置观察者模式

1:结构


注意:此处的Observable不是接口而是一个类。


2:示例代码

<span style="font-size:18px;">public class NewsPaperOffice extends Observable     //此处使用java.util.Observable{    private int testFlag;    public NewsPaperOffice(){ }     //构造器不再需要为了记住观察者们而建立数据结构    public void testFlagChanged()    {        setChanged();       //在调用notifyObservers()之前, 要先调用setChanged()来指示状态已经改变        notifyObservers();    }    /**     * 观察者通过这种方法取得NewsPaperOffice对象的状态     * @return     */    public int getTestFlag()    {        return testFlag;    }    public void setTestFlag(int testFlag)    {        this.testFlag=testFlag;    }}public class GeneralDisplay implements Observer,DisplayElement  //此处用的是java.util.Observer{    Observable observable;    private int testFlag;    public GeneralDisplay(Observable observable)    {        this.observable=observable;        observable.addObserver(this);    }    @Override    public void display() {        System.out.println("testFlag="+testFlag);    }    @Override    public void update(Observable o, Object arg)    {        if(o instanceof NewsPaperOffice)        {            NewsPaperOffice newsPaperOffice=(NewsPaperOffice)o;            this.testFlag=newsPaperOffice.getTestFlag();            display();        }    }}public class DomensticDisplay{    public static void main(String[] args)    {        NewsPaperOffice newsPaperOffice=new NewsPaperOffice();        GeneralDisplay generalDisplay=new GeneralDisplay(newsPaperOffice);        newsPaperOffice.setTestFlag(3);        newsPaperOffice.testFlagChanged();    }}</span>


三、自定义和内置模式对比

1:内置模式实现通知观察者的顺序是不固定的,而自定义模式顺序是固定的;

2:java.util.Observable是一类,如果Observable有一个别的父类,则会冲突,并且违反了多用组合少用继承的设计原则。


0 0
原创粉丝点击