观察者模式

观察模式UML图及各部分定义:

Subject:抽象主题,定义注册、删除、通知观察者的接口

Observer:抽象观察者,为所有的具体观察者定义一个响应的接口,在接受到主题发来的通知后,及时更新自己。

Atcor:抽象观察者的行为,定义了观察者在接受通知更新自己后,接下来要做的动作。(该部分也可以放到Observer里面,但是这样每个观察者就必须实现该接口了,显得不灵活)

ConcreteSubject:  具体主题,在具体主题内部状态发生改变时,给所有注册过的观察者发出通知。

ConcreteObserver: 具体观察者,实现抽象观察者角色所要求的更新接口,以便使自己内部的状态和具体保持一致。 此外还可根据自身需要实现抽象观察者角色的行为。


(一) Subject
//抽象目标类Subject
public interface Subject {
public void registerObserver(Observer o);
    public void removeObserver(Observer o);
    public void notifyObserver();
}

复制代码
//具体目标类
public class WeatherData implements Subject {
  //内部维护一个list集合
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData(){
        this.observers = new ArrayList<Observer>();
    }
    @Override
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    @Override
    public void removeObserver(Observer o) {
        observers.remove(o);
    }

    @Override
    public void notifyObserver() {
        for(int i = 0; i < observers.size(); i++ ){
            Observer observer = (Observer) observers.get(i);
       //将改变传递给观察者
            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;
    }
}
复制代码

 

(二)Observer

//抽象观察者
public interface Observer {
    public void update(float temp, float humidity, float pressure);
}

 

//观察者行为
public interface Displayment {
    public void display();
}

 

复制代码
//具体观察者1
public class CurrentConditionsDisplay implements Observer, Displayment{
    private float temp;
    private float humidity;
    private Subject weatherData;

    public void CurrentConditionsDisplay(Subject weatherData){
        this.weatherData = weatherData;
    }

    public void display() {
        System.out.println("Current conditions: " + temp + "F degrees and "+ humidity + " % humidity");
    }

    public void update(float temp, float humidity, float pressure) {
        this.temp = temp;
        this.humidity = humidity;
        display();
    }
}
复制代码

 

(三)Test

复制代码
//测试
public class WeatherDataTest extends TestCase {

    public void testRegisterObserver() {
        WeatherData weatherData = new WeatherData();
        weatherData.setMeasurements(23,15,175);
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay();
//        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);
        weatherData.registerObserver(currentConditionsDisplay);
        weatherData.measurementsChanged();
        weatherData.removeObserver(currentConditionsDisplay);
        weatherData.notifyObserver();
    }
}
复制代码

 

//测试结果
Current conditions: 23.0F degrees and 15.0 % humidity

posted @   小兵要进步  阅读(26)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 【杭电多校比赛记录】2025“钉耙编程”中国大学生算法设计春季联赛(1)

侧边栏
点击右上角即可分享
微信分享提示