设计模式(一)观察者模式

观察者模式 定义了对象之间的一对多的依赖,这样一来,当一个对象状态改变时,他的

多有依赖都会受到通知并自动更新。

本例为一个温度基站,和三个终端。温度基站为广播类WeatherData,三个终端监听者类分别为:TVDispaly,FactoryDisplay,MobileDisplay

其中,Observable为广播类父类,含有基本的方法。

Observer类为监听者接口,监听者需实现updata方法。

Display为显示接口,需实现display方法。

ObserverDemo为测试类。

下面直接上代码,注释很清晰。基本上很容易理解。

Observable.java

package observer;
/*
 * @author trojan
 * 广播类的父类
 *
 */
public class Observable {
    protected boolean change = false;

    public void setChanged() {
        change = true;
    }

    public void notifyObservers(Object arg) {}
    public void notifyObservers(){ notifyObservers(null);}
    public void addObserver(Observer observer){}
}

WeatherData.java

package observer;
/*
 * @author trojan
 * 该类为广播类
 */
import java.util.ArrayList;

public class WeatherData extends Observable {
    //温度
    private float temperature;
    //湿度
    private float humidity;
    //污染指数
    private float pollution_index;
    ArrayList<Observer> observers = new ArrayList<Observer>();

    public WeatherData(){ }

    //增加监听者
    public void addObserver(Observer observer){
        observers.add(observer);
    }

    //将更改广播给所有监听者
    public void notifyObservers(Object arg) {
        if(change){
            for(Observer observer : observers){
                observer.update(this,arg);
            }
        }
        change = false;
    }

    public void notifyObservers() { notifyObservers(null);}

    public void stateChange() {
        //调用notifyObservers之前应调用状态改变标志函数
        setChanged();
        notifyObservers();
    }

    //设置状态后,将调用stateChange函数,通知监听者
    public void setState(float temperature, float humidity, float pollution_index) {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pollution_index = pollution_index;
        stateChange();
    }

    public float getTemperature() {
        return temperature;
    }
    public void setTemperature(float temperature) {
        this.temperature = temperature;
    }
    public float getHumidity() {
        return humidity;
    }
    public void setHumidity(float humidity) {
        this.humidity = humidity;
    }
    public float getPollution_index() {
        return pollution_index;
    }
    public void setPollution_index(float pollution_index) {
        this.pollution_index = pollution_index;
    }

}

Display.java

package observer;
/*
 * @author
 * 显示接口
 */
public interface Display {
    public void display();
}

Observer.java

package observer;
/*
 * @author trojan
 * 这是一个监听者的接口,需要实现updata方法
 * 该方法可以被广播者调用,向监听者广播数据,或者说是一种推的方式
 * 监听者可以可以调用该方法主动更新数据,就像是一种拉的方式
 * 当然,对于每一个实现的监听者可能会有不同的数据需求
 * 所以,他们可以实现对自己感兴趣的那部分数据更新
 *
 */
public interface Observer {
    public void update(Object obj,Object arg);;
}

TVDisplay.java

package observer;
/*
 * @author trojan
 * 对于电视台来说可能需要的气象数据要比其他的设备多
 * 所以updata需要更新更多的数据
 */
public class TVDisplay implements Observer, Display{
    Observable observable;
    private float temperature;
    private float humidity;
    private float pollution_index; 

    //变成一个监听者
    public void becomeOberser(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);;
    }

    @Override
    public void update(Object obj, Object arg) {
        if(obj instanceof WeatherData){
            WeatherData weatherData = (WeatherData)obj;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            this.pollution_index = weatherData.getPollution_index();
        }

    }

    @Override
    public void display() {
        System.out.println("WeatherData:\n"
                + "temperature: "+temperature +"\n"
                +"humidity"+humidity+"\n"
                +"pollution_index:"+pollution_index);

    }

}

FactoryDisplay.java

package observer;
/*
 * @author torjan
 * 工厂显示平台所需要的广播数据
 *
 */
public class FactoryDisplay implements Observer, Display{

    Observable observable;
    private float temperature;
    private float pollution_index; 

    //变成一个监听者
    public void becomeOberser(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);;
    }

    @Override
    public void update(Object obj, Object arg) {
        if(obj instanceof WeatherData){
            WeatherData weatherData = (WeatherData)obj;
            this.temperature = weatherData.getTemperature();
            this.pollution_index = weatherData.getPollution_index();
        }

    }

    @Override
    public void display() {
        System.out.println("WeatherData:\n"
                + "temperature: "+temperature +"\n"
                +"pollution_index"+pollution_index);

    }

}

MobileDisplay.java

package observer;
/*
 * @author
 * 手机平台所需要的广播数据
 *
 */
public class MobileDisplay implements Observer, Display {

    Observable observable;
    private float temperature;
    private float humidity;

    //变成一个监听者
    public void becomeOberser(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);;
    }

    @Override
    public void update(Object obj, Object arg) {
        if(obj instanceof WeatherData){
            WeatherData weatherData = (WeatherData)obj;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
        }

    }

    @Override
    public void display() {
        System.out.println("WeatherData:\n"
                + "temperature: "+temperature +"\n"
                +"humidity"+humidity);

    }

}

测试类:

ObserverDemo.java

package observer;

public class ObserverDemo {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        FactoryDisplay factoryDisplay = new FactoryDisplay();
        MobileDisplay mobileDisplay = new MobileDisplay();
        TVDisplay tvDisplay = new TVDisplay();

        weatherData.addObserver(factoryDisplay);
        weatherData.addObserver(mobileDisplay);;
        tvDisplay.becomeOberser(weatherData);

        weatherData.setState(23, 70, 120);

        factoryDisplay.display();
        mobileDisplay.display();
        tvDisplay.display();
    }
}

测试结果:

WeatherData:
temperature: 23.0
pollution_index120.0
WeatherData:
temperature: 23.0
humidity70.0
WeatherData:
temperature: 23.0
humidity70.0
pollution_index:120.0

总结:

设计原则:找出程序中会变化的方面,然后根据其和固定不变的方面相分离

在观察者模式中,会改变的是主题的状态,以及观察者的数目和种类。用这个模式,可以改变依赖于主题状态的对象,却不必改变主题。

设计原则:针对接口编程,不针对实现编程

设计原则:多用组合,少用继承

时间: 2024-08-01 10:30:39

设计模式(一)观察者模式的相关文章

【设计模式】观察者模式

生活中,当某件事发生时,应该通知所有的相关者.例如,上课地点有变,要通知所有学习这门课的同学. 在软件设计中,当一个对象的状态发生变化是,如何通知与它相关的所有对象,就是我们今天要谈到的观察者模式. 观察者模式 概述 定义了一种一对多的依赖关系.让多个观察者对象同事监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有的观察者对象,使它们能够自动更新自己. 实际上,观察者模式所做的工作就是在解除耦合.让耦合的双方都依赖于抽象,而不是依赖于具体.从而使得各自的变化都不会影响另一边的变化. 结

设计模式:观察者模式

设计模式:观察者模式 : http://www.cnblogs.com/li-peng/archive/2013/02/04/2892116.html 观察者模式是我们经常用的一个模式,比如在用wcf做服务的时候通知客户端做一些操作一般用设计者模式. 今天做一个订报纸的小例子来理解一下观察者模式  出版者+订阅者=观察者模式 用下边的图来说就是    人民日报+订阅者=观察者模式 只要是订阅了人民日报的人,有了新报纸就会送到订阅者那里去, 当你不想订的时候取消就不订阅就不会再收到报纸了. //报

设计模式之-观察者模式

该文代码来自设计模式之惮一书. 观察者模式定义: 观察者模式也叫做发布订阅模式. 观察者模式中的角色: 1.被观察者 被观察者职责为管理观察者并通知观察者. 2.观察者 对接受到的消息进行处理. /// <summary> /// 被观察者 /// </summary> public abstract class Subject { /// <summary> /// 观察者集合 /// </summary> private List<IObserva

设计模式(16) 观察者模式(OBSERVER)C++实现

意图: 定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新. 动机: 将一个系统设计成一系列相互协作的类有一个常见的副作用:需要维护相关对象之间的一致性. 观察者模式定义一种交互,即发布-订阅: 一个对象当自身状态发生改变时,会发出通知,但是并不知道谁是他的接收者,但每个接收者都会接收到通知,这些接受者称为观察者. 作为对通知的响应,每个观察者都将查询目标状态,然后改变自身的状态以和目标状态进行同步. 使用场景: 使对象封装为独立的改变和使用:

&lt;&lt;Head First设计模式&gt;&gt;之观察者模式学习

1.概念 定义了对象之间的一对多依赖关系,当一个对象(主题对象)的状态改变时,它的所有依赖者(观察者对象)都会收到通知并自动更新. 2.优势 观察者模式实现了主题对象与观察者对象之间的松耦合,当有新的观察者时,无需修改主题对象的代码,只需要新的观察者对象实现接口.在程序运行的过程中,可以随时注册和删除观察者而不影响主体对象. 观察者模式使主题(Subject)对象和观察者(Observer)对象都可以被轻易地复用. 3.Java中观察者模式 Java API有内置的观察者模式,java.util

大话设计模式_观察者模式(Java代码)

观察者模式:定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象.这个主题对象在状态发生变化时,会通知所有观察者对象,使他们自己能够自动更新自己.简单描述:1个Subject类(可以是抽象类可以是接口),可以有多个具体Subject类(继承抽象Subject),此具体Subject持有多个观察者的引用,在此具体Subject状态发生变化的时候调用这些观察者的相应方法.另外,这些持有的引用是抽象的,不是具体的,而这些引用所指向的对象时具体的观察者(即需要作出更新的具体观察者,这些具体

设计模式-观察者模式(Observer Pattern)

今天看了看观察者模式,有点小小的体会,从以下3点说明之 : 1.看一下经典的观察者模式图 2.讲个故事,说一下逻辑 有一个男人(Subject),他通过一定的手段(attach)拥有了3个女人(Observer):老婆(concreteObserver1),情人(concreteObserver2),小3(concreteObserver3).这3个女人都不知情,但是都想知道男人的月收入情况.而月收入需要通过工资卡(concreteSubject)来体现.所以,每当发工资(setState)时,

常用设计模式之观察者模式 + 事件委托

常用设计模式之观察者模式 + 事件委托 作用及UML (摘自<大话设计模式>) Code 1 abstract class Subject{ 2 protected String state; 3 public void setState(String state){this.state = state;} 4 public String getState(){return this.state;} 5 6 private List<Observer> observers = ne

跟我学设计模式视频教程——观察者模式,迭代器模式

课程视频 观察者模式 迭代器模式 课程笔记 课程笔记 课程代码 课程代码 新课程火热报名中 课程介绍 跟我学设计模式视频教程--观察者模式,迭代器模式,布布扣,bubuko.com

设计模式之观察者模式C++实现

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会收到通知并自动更新. 观察者模式结构图如下: 举例: 气象系统有三个部分分别是气象站(获取实际气象数据的物理装置),WeatherData对象(用来追踪来自气象站的数据,并更新布告板)和布告板(显示目前天气状况给用户看).WeatherData对象知道如何根物理气象站联系,以取得更新信息.WeatherData对象会随机更新三个布告板的显示:目前状况(温度,湿度,气压).气象统计和天气预报.我们的工作是建立一