Java设计模式-观察者模式

Posted Frank Q

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java设计模式-观察者模式相关的知识,希望对你有一定的参考价值。

本文主要介绍的是Java观察者模式的理解与基本实现的Demo;在学习设计模式的时候,需要考虑的是为什么会出现这种模式,为什么我们需要使用这种模式,类比到我们生活中一个熟悉的场景理解意义,落实到代码上确实的理解到什么是该模式,以及该模式的代码实现上与普通实现的区别在哪,为什么使用了该模式之后项目的开发在遇到改变或者其他情况的时候会比较容易修改和更新;以上是我在学习与使用设计模式的时候一些感想;
本文中demo来自于HeadFirst设计模式,特此声明;


1、观察者模式初识
2、观察者模式运用
3、观察者模式实现


1、观察者模式初识

首先是两个例子:
1、情景一:在学校的时候,咱们老师要通知某件事情的时候会走进教室给大家说该通知(notifyAll),但是,有些同学并不需要遵循该通知,所以老师就请该同学暂时不用听(remove),当然如果隔壁班的老师有事儿,这个时候我们就会请那个班的班长来我们班(add),一起接受该通知,回头,该班长就会将该通知传递给他们班的同学(该班长在这个时候就有事观察者有事被观察者);
2、情景二:如果需要写一个天气通知的程序,我们可以动态的从天气站获取数据,但是我们通知的时候假设有三个展板,每个展板依次是天气预告、天气统计、目前状况,并且我们可能随时移除或者添加新的具有混合信息的展板,在这个时候,观察者模式就起到了很大作用了;


2、观察者模式运用

情景:还是一个情景:报纸与杂志的订阅:
报社出版报纸,当我们想报社订阅报纸(订阅就是add)的时候只要有新的报纸出版就会给我们寄送过来(通知就是notify),当我们不想再阅读报纸的时候只需要取消订阅即可(取消订阅就是remove),在有新的报纸出版的时候(也就是所谓的信息改变)就不会有通知;

出版者(报社) + 订阅者 = 观察者模式
Subject + Observer = 观察者模式


3、观察者模式实现(以1种的情景二作为例子)

Subject.java

public interface Subject 
    // 注册观察者
    public void registerObserver(Observer o);

    // 移除观察者
    public void removeObserver(Observer o);

    // 通知所有观察者
    public void notifyObserver();

Observer.java

public interface Observer 
    // 观察者使用方法获取主题数据
    public void update(float temperature , float humidity , float pressure);

WeatherData.java(天气信息)

import java.util.ArrayList;

public class WeatherData implements Subject 

    // 存储当前的所有观察者
    // 使用链表方便添加与移除的操作
    private ArrayList<Observer> observers;

    // 温度,湿度,气压数据
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() 
        observers = new ArrayList<Observer>();
    

    @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(o);
        
    

    @Override
    public void notifyObserver() 
        for (Observer observer : observers) 
            observer.update(temperature, humidity, pressure);
        
    

    // 当发生改变的时候通知所有的观察者
    public void measurementsChanged() 
        // 发送改变调用该方法
        notifyObserver();
    

    // 设置信息,当信息发送变化进行通知操作
    public void setMeasurements(float temperature, float humidity, float pressure) 
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    

DisplayElement.java(展示)

public interface DisplayElement 
    // 布告板需要显示的时候调用此方法
    public void display();

CurrentCondiDisplay.java (其中一块天气信息的展示)

public class CurrentCondiDisplay implements Observer , DisplayElement 

    private float temperature;
    private float humidity;
    // 提供信息的主题
    @SuppressWarnings("unused")
    private Subject weatherData;

    public CurrentCondiDisplay(Subject weatherData) 
        this.weatherData = weatherData;
        // 当生成该对象的时候自动添加到可以观察的链表中
        weatherData.registerObserver(this);
    

    @Override
    public void display() 
        System.out.println("CurrentCondiDisplay [temperature=" + temperature
                + ", humidity=" + humidity + "]");
    

    @Override
    public void update(float temperature, float humidity, float pressure) 
        this.temperature = temperature;
        this.humidity    = humidity;
        display();
    

WeatherStation.java(天气信息展示的测试)

public class WeatherStation 

    public static void main(String[] args) 
        WeatherData weatherData = new WeatherData();
        // 注册观察者
        @SuppressWarnings("unused")
        CurrentCondiDisplay currentCondiDisplay = new CurrentCondiDisplay(weatherData);
        weatherData.setMeasurements(80, 65.0f, 30.4f);
    

类图:

以上是关于Java设计模式-观察者模式的主要内容,如果未能解决你的问题,请参考以下文章

Android常用设计模式

观察者模式

设计模式之观察者模式

Head First Design Patten观察者模式

Head First Design Patten观察者模式

设计模式整理_观察者模式