23种java设计模式之观察者模式

来源:互联网 发布:神盾内网管理软件 编辑:程序博客网 时间:2024/06/09 22:37

在讲观察者模式之前,我们还是用一个案例来说明一下。

小明的上司又有新任务给他了,让他做一个和Internet气象站合作的项目。项目所需要的数据类是气象站提供的,小明公司主要任务是提供温度、气压和湿度的接口,测量数据更新时需时时通知给第三方,需要设计开放型API便于其他第三方公司也能接入气象站获取数据。

小明一开始是用普通的OO思想去做的。

首先,气象站提供了WeatherData类:


然后小明根据这个设计了整体的设计方案,CurrentConditions为数据公告板,用来显示数据:


设计代码:

气象站提供的WeatherData类:

public class WeatherData {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度
private CurrentConditions currentConditions;//显示器

public WeatherData(CurrentConditions currentConditions){
this.currentConditions=currentConditions;
}

public float getmTemperatrue() {
return mTemperatrue;
}
public float getmPressure() {
return mPressure;
}
public float getmHumidity() {
return mHumidity;
}

public void dataChange(){
currentConditions.update(getmTemperatrue(), getmPressure(), getmHumidity());;
}

public void setData(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
dataChange();
}
}

小明开发些的显示板CurrentConditions类:

public class CurrentConditions {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public void update(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
display();
}

public void display(){
System.out.println("今天的温度是"+mTemperatrue);
System.out.println("今天的气压是"+mPressure);
System.out.println("今天的湿度是"+mHumidity);
}
}

测试类Test:

public class Test {
public static void main(String[] args) {
CurrentConditions currentConditions;
WeatherData weatherData;
currentConditions=new CurrentConditions();
weatherData=new WeatherData(currentConditions);
weatherData.setData(30, 150, 20);
}
}

这样总体的功能就出来了,但是这样的话,当第三方接入的话就不好维护了,在dataChange()方法里面肯定要加入第三方的公告板的更新函数,所以就必须在WeatherData构造方法里面添加参数或者再添加一个函数,每增加一个公司

就必须在dataChange()方法添加一部分代码,这样会导致每次有WeatherData接口函数要重新编译一遍,无法动态的添加第三方。

对于这个问题,小明对项目进行改进,方案如下:


先把公告板抽离出来,写一个Observer接口类:

public interface Observer {
public void update(float mTemperatrue,float mPressure,float mHumidity);
}

今天的公告板CurrentCondition类:

public class CurrentCondition implements Observer {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public void update(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
display();
}

public void display(){
System.out.println("今天的温度是"+mTemperatrue);
System.out.println("今天的气压是"+mPressure);
System.out.println("今天的湿度是"+mHumidity);
}
}

明天的公告板NextCondition类:

public class NextCondition implements Observer {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public void update(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
display();
}

public void display(){
System.out.println("明天的温度是"+mTemperatrue);
System.out.println("明天的气压是"+mPressure);
System.out.println("明天的湿度是"+mHumidity);
}

}

对于数据类,我们给他注册,移除,和通知,为了更合理的完善项目,写一个Subject接口类:

public interface Subject {
public void registerObserver(Observer o);
public void removeObserver(Observer o);
public void notifyObserver();
}

然后数据类实现Subject类的WeatherData类:

public class WeatherData implements Subject {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度
private ArrayList<Observer> observers;

public WeatherData() {
observers = new ArrayList<Observer>();
}
public float getmTemperatrue() {
return mTemperatrue;
}
public float getmPressure() {
return mPressure;
}
public float getmHumidity() {
return mHumidity;
}
public void dataChange(){
notifyObserver();
}

public void setData(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
dataChange();
}

public void registerObserver(Observer o) {
observers.add(o);
}


public void removeObserver(Observer o) {
if(observers.contains(o)){
observers.remove(o);
}
}

public void notifyObserver() {
for(int i=0;i<observers.size();i++){
observers.get(i).update(getmTemperatrue(), getmPressure(), getmHumidity());
}
}
}

这样就可以实现灵活的添加第三方公司,使项目的拓展性得以体现。

测试类Test:

public class Test {
public static void main(String[] args) {
CurrentCondition currentConditions=new CurrentCondition();
NextCondition nextCondition=new NextCondition();
WeatherData weatherData=new WeatherData();
weatherData.registerObserver(currentConditions);
weatherData.registerObserver(nextCondition);
weatherData.setData(111, 222, 333);
weatherData.removeObserver(currentConditions);
weatherData.setData(333, 555, 666);
}
}

当然,还可以用java内置观察者,它的作用和观察者方法一样,它本身提供了注册,移除,通知功能,Observable(这是个类,而不是接口,所以只能继承,而不能实现)和Observer(这是个接口)是java内置观察者提供的,下面用java内置观察者来实现上面的功能:

WeahterData 类:

public class WeahterData extends Observable {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public float getmTemperatrue() {
return mTemperatrue;
}
public float getmPressure() {
return mPressure;
}
public float getmHumidity() {
return mHumidity;
}
public void dataChange(){
this.setChanged();
this.notifyObservers(new Data(getmTemperatrue(),getmPressure(),getmHumidity()));
}

public void setData(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
dataChange();
}


        //这里提供一个数据类
public class Data{
float mTemperatrue;//温度
float mPressure;//气压
float mHumidity;//湿度

public Data(float mTemperatrue,float mPressure,float mHumidity){
this.mTemperatrue=mTemperatrue;
this.mPressure=mPressure;
this.mHumidity=mHumidity;
}
}
}

CurrentCondition 类:

public class CurrentCondition implements Observer {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public void update(Observable arg, Object arg1) {
this.mTemperatrue=((Data)arg1).mTemperatrue;
this.mPressure=((Data)arg1).mPressure;
this.mHumidity=((Data)arg1).mHumidity;
display();

}
public void display(){
System.out.println("今天的温度是"+mTemperatrue);
System.out.println("今天的气压是"+mPressure);
System.out.println("今天的湿度是"+mHumidity);
}
}

NextCondition 类:

public class NextCondition implements Observer {
private float mTemperatrue;//温度
private float mPressure;//气压
private float mHumidity;//湿度

public void update(Observable arg, Object arg1) {
this.mTemperatrue=((Data)arg1).mTemperatrue;
this.mPressure=((Data)arg1).mPressure;
this.mHumidity=((Data)arg1).mHumidity;
display();

}
public void display(){
System.out.println("明天的温度是"+mTemperatrue);
System.out.println("明天的气压是"+mPressure);
System.out.println("明天的湿度是"+mHumidity);
}
}

测试类Test:

public class Test {
public static void main(String[] args) {
CurrentCondition currentConditions=new CurrentCondition();
NextCondition nextCondition=new NextCondition();
WeahterData weatherData=new WeahterData();
weatherData.addObserver(currentConditions);
weatherData.addObserver(nextCondition);
weatherData.setData(39, 123, 45);
weatherData.deleteObserver(currentConditions);
weatherData.setData(40, 213, 50);
}
}

总结:

观察者模式:对象之间多对一依赖的一种设计方案,以便一个对象的状态发送变化时,所有依赖于它的对象都得到通知并自动刷新。就相当于气象站给出的数据变化时,每个显示板的数据也会跟着刷新。

0 0
原创粉丝点击