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

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wode_dream/article/details/49124207

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

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

     实现:在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有一个别的父类,则会冲突,并且违反了多用组合少用继承的设计原则。


猜你喜欢

转载自blog.csdn.net/wode_dream/article/details/49124207