自从jack的鸭子游戏得到成功之后,jack的好朋友夏流就觉得心里痒痒的,也想做出一番作为来。
所以,今天的主人公就是这位夏流童鞋。夏流是钱塘江观测站的一名观测员,需要向人民群众反馈钱塘江的水位,水温,风力,及水里的鱼量等信息。在这里经常会有许多市民从他这里打听当日的钱塘江的这些信息,以便于他们了解,好决定是不是要去江边做点什么。
于是夏流决定做一个系统,能够自动反馈钱塘江的信息给热心市民。每当钱塘江的相关信息有变化时,会自动发送到热心市民手机上,通知他们。
在观察者模式中,夏流做的这个钱塘江观测系统便是一个主题(Subject),热心市民便是一个观察者(Observer)
我们定义两个接口Subject和Observer ,因为我们是有格局,有情怀的程序猿,所以一般我们都是要面向接口编程。
在Subject中,我们定义三个方法,添加观察者,删除观察者,通知观察者。
在Observer中,只要更新主题发过来的消息就好,所以只有一个更新方法。
然后我们实现具体主题,也就是钱塘江观测站,在钱塘江观测站中,水位,水温,风力,鱼的条数都是它的属性,还有一个是观察者列表,所有的观察者都存在这个ObserverList里。当有新的信息更新时,他就调用notifyObserver方法通知他们的观察者去更新信息。
接着呢是实现观察者了,这个市民就是具体的观察者了。观察者中维护了一个主题,这个主题就是他关注的那个主题,也就是钱塘江观测站了,它有了这个主题就能够把自己给添加到这个主题的观察者列表中了。
夏流按照这个思路设计完了该系统,却遭到了一些热心市民的抱怨。一位爱钓鱼的王大伯说,我只要当天的水位和鱼的数量信息,其他信息这么多给我并没有软用。
另一位爱游泳的刘叔叔说,我只要水温很风力信息就够了,这样我才能知道我该不该下水游泳(当然在钱塘江游泳钓鱼啥的都是非常危险的,这里只是举个例子)
另一位爱拍照的王阿姨说,我只要风力信息,希望我能借助风力吹起我美丽的秀发,用我的美颜相机定格住那美丽的瞬间
夏流听到了各位热心市民的意见,决定改善一下系统。
他想这样的话,就在通知观察者的时候,让update方法不带参数。反正他们内部已经维护了一个主题,让他们自己根据自己所需去从这个主题中拿数据就好了。
以下是修改后的类图
主要还是修改观察者中的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);
}
}
运行结果:
有了这个设计,夏流童鞋不仅受到了大伯大妈的好评,也帮助他成为杭州杰出青年的好榜样。
观察者模式的官方定义是:定义对象见的一种一对多的依赖关系,当一个对象的状态发送变化时,所有依赖它的对象都得到通知并被自动更新。