我的武林秘籍设计模式之观察者模式

自从jack的鸭子游戏得到成功之后,jack的好朋友夏流就觉得心里痒痒的,也想做出一番作为来。

所以,今天的主人公就是这位夏流童鞋。夏流是钱塘江观测站的一名观测员,需要向人民群众反馈钱塘江的水位,水温,风力,及水里的鱼量等信息。在这里经常会有许多市民从他这里打听当日的钱塘江的这些信息,以便于他们了解,好决定是不是要去江边做点什么。

于是夏流决定做一个系统,能够自动反馈钱塘江的信息给热心市民。每当钱塘江的相关信息有变化时,会自动发送到热心市民手机上,通知他们。

在观察者模式中,夏流做的这个钱塘江观测系统便是一个主题(Subject),热心市民便是一个观察者(Observer)

我们定义两个接口Subject和Observer ,因为我们是有格局,有情怀的程序猿,所以一般我们都是要面向接口编程。

在Subject中,我们定义三个方法,添加观察者,删除观察者,通知观察者。

在Observer中,只要更新主题发过来的消息就好,所以只有一个更新方法。

然后我们实现具体主题,也就是钱塘江观测站,在钱塘江观测站中,水位,水温,风力,鱼的条数都是它的属性,还有一个是观察者列表,所有的观察者都存在这个ObserverList里。当有新的信息更新时,他就调用notifyObserver方法通知他们的观察者去更新信息。

接着呢是实现观察者了,这个市民就是具体的观察者了。观察者中维护了一个主题,这个主题就是他关注的那个主题,也就是钱塘江观测站了,它有了这个主题就能够把自己给添加到这个主题的观察者列表中了。


我的武林秘籍设计模式之观察者模式_第1张图片

夏流按照这个思路设计完了该系统,却遭到了一些热心市民的抱怨。一位爱钓鱼的王大伯说,我只要当天的水位和鱼的数量信息,其他信息这么多给我并没有软用。

另一位爱游泳的刘叔叔说,我只要水温很风力信息就够了,这样我才能知道我该不该下水游泳(当然在钱塘江游泳钓鱼啥的都是非常危险的,这里只是举个例子)

另一位爱拍照的王阿姨说,我只要风力信息,希望我能借助风力吹起我美丽的秀发,用我的美颜相机定格住那美丽的瞬间

夏流听到了各位热心市民的意见,决定改善一下系统。

他想这样的话,就在通知观察者的时候,让update方法不带参数。反正他们内部已经维护了一个主题,让他们自己根据自己所需去从这个主题中拿数据就好了。

以下是修改后的类图


我的武林秘籍设计模式之观察者模式_第2张图片

主要还是修改观察者中的update方法,一个是直接通过update方法一股脑把所有信息传过来,另一个是通过观察者自身所维护的主题中去取。

接着有了这个设计,我们好实现代码了

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public interface Observer {

void update();

    void display();

}

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public interface Subject {

void addObserver(Observer observer);

    void deleteObserver(Observer observer);

    void notifyObserver();

}

package qiantang;

import java.util.ArrayList;

import java.util.List;

/**

* Created by huangx on 2018/11/14.

*/

public class QiangtangRiverStationimplements Subject {

private int height;

    private int tempature;

    private int wind;

    private int fish;

    private ListobserverList =new ArrayList();

    public void addObserver(Observer observer) {

observerList.add(observer);

    }

public void deleteObserver(Observer observer) {

observerList.remove(observer);

    }

public void notifyObserver() {

for (Observer observer :observerList) {

observer.update();

        }

}

public void setNewInfo(int height, int tempature, int wind, int fish) {

this.height = height;

        this.tempature = tempature;

        this.wind = wind;

        this.fish = fish;

        notifyObserver();

    }

public int getHeight() {

return height;

    }

public int getTempature() {

return tempature;

    }

public int getWind() {

return wind;

    }

public int getFish() {

return fish;

    }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class FishCitizenimplements Observer {

private Stringname;

    private int fish;

    private int height;

    private Subjectsubject;

    public FishCitizen(String name, Subject subject) {

this.name = name;

        this.subject = subject;

        subject.addObserver(this);//关键一步把自己扔到主题中去

    }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.fish = ((QiangtangRiverStation)subject).getFish();

            this.height = ((QiangtangRiverStation)subject).getHeight();

        }

display();

    }

public void display() {

System.out.println("我是" +name +",今天的鱼量是" +fish +",今天 的水位是" +height);

    }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class SwimCitizenimplements Observer {

private Stringname;

    private int tempature;

    private int wind;

    private Subjectsubject;

    public SwimCitizen(String name, Subject subject) {

this.name = name;

        this.subject = subject;

        subject.addObserver(this);

    }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.tempature = ((QiangtangRiverStation)subject).getTempature();

            this.wind = ((QiangtangRiverStation)subject).getWind();

        }

display();

    }

public void display() {

System.out.println("我是" +name +",今天的温度是" +tempature +",今天 的风力是" +wind);

    }

}


package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class PhotoCitizenimplements Observer {

private Stringname;

    private int wind;

    private Subjectsubject;

    public PhotoCitizen(String name, Subject subject) {

this.name = name;

        this.subject = subject;

        subject.addObserver(this);

    }

public void update() {

if (subject instanceof QiangtangRiverStation) {

this.wind = ((QiangtangRiverStation)subject).getWind();

        }

display();

    }

public void display() {

System.out.println("我是" +name +",今天的风力是" +wind +"今天的我一定是个小公举");

    }

}

package qiantang;

/**

* Created by huangx on 2018/11/14.

*/

public class TestApplication {

public static void main(String[] args) {

QiangtangRiverStation qiangtangRiverStation=new QiangtangRiverStation();

        SwimCitizen swimCitizen=new SwimCitizen("刘叔叔",qiangtangRiverStation);

        FishCitizen fishCitizen=new FishCitizen("王大伯",qiangtangRiverStation);

        PhotoCitizen photoCitizen=new PhotoCitizen("王阿姨",qiangtangRiverStation);

        qiangtangRiverStation.setNewInfo(11,22,33,44);

        qiangtangRiverStation.setNewInfo(55,66,77,88);

    }

}

运行结果:

我的武林秘籍设计模式之观察者模式_第3张图片

有了这个设计,夏流童鞋不仅受到了大伯大妈的好评,也帮助他成为杭州杰出青年的好榜样。

观察者模式的官方定义是:定义对象见的一种一对多的依赖关系,当一个对象的状态发送变化时,所有依赖它的对象都得到通知并被自动更新。

你可能感兴趣的:(我的武林秘籍设计模式之观察者模式)