大话设计模式——观察者模式(一)

本文介绍了一种设计模式——观察者模式,它定义了对象间的一对多依赖关系,当一个对象的状态发生变化时,所有依赖的对象都会自动更新。文章通过一个天气预报的例子详细解释了这一模式的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、概念

1.1 定义

定义对象间的一种一对多的依赖关系。当一个对象(被观察者)的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新(观察者)。

1.2 实例场景

小陈在气象局工作,可以为他的家人提供最新的天气情况。这时,小陈就是被观察者,他的家人就是观察者。他的家人订阅天气服务,小陈就可以提供最新的天气预报到订阅者手中。而他的家人收到通知后,可以做出自己的反应。

二、通用代码

2.1 目标类

这里的目标类对应着实例里的小陈,他知道观察自己的观察者(家人),并提供了注册和删除观察者的接口。

public class Subject {
    private ArrayList<Observer> observers = new ArrayList<Observer>();
    /**
     * 添加
     * @param observer 观察者
     */
    public void attach(Observer observer) {
        observers.add(observer);
    }

    /**
     * 删除
     * @param observer 观察者
     */
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 向所有注册的观察者发送信息
     */
    protected void notifyObservers(){
        for(Observer observer:observers){
            observer.update(this);
        }
    }

}

2.2 具体目标类

这个类就相当于是天气预报的功能,负责把有关的状态存入到相应的观察者对象中。

public class ConcreatSubject extends Subject {
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
        this.notifyObservers();
    }

}

2.3 观察者接口

此类为观察者的接口,提供了一个更新的接口,当目标发生改变时,通知相应的观察者

public interface Observer {
    /**
     * 更新的接口
     * @param subject subject 传入目标对象,方便获取目标的状态
     */
    void update(Subject subject);
}

2.4 具体的观察者对象

这个类就相当于实例的小陈的家人,他的家人知道天气变化了之后,会采取不同的策略去改变一些事。

public class ConcreatObserver implements Observer {
    //观察者状态
    private String observerState;

    /**
     * 获取目标类的状态,同步到观察者中
     */
    @Override
    public void update(Subject subject) {
        observerState = ((ConcreatSubject)subject).getSubjectState();
    }

}

2.5 总结

这样,我们就可以通过改变ConcreatSubject里的状态值,通过循环来通知每一个注册了的观察者,让他们也做出相应的改变。

三、详细设计

3.1 天气目标类

public class WeatherSubject {
    //用来保存注册的观察者对象
    private ArrayList<Observer> observers = new ArrayList<Observer>();
    /**
     * 把订阅天气的人添加到订阅者列表中
     * @param observer 观察者
     */
    public void attach(Observer observer) {
        observers.add(observer);
    }

    /**
     * 删除订阅天气的人
     * @param observer 观察者
     */
    public void detach(Observer observer) {
        observers.remove(observer);
    }

    /**
     * 通知所有已经订阅了天气的人
     */
    protected void notifyObservers(){
        for(Observer observer:observers){
            observer.update(this);
        }
    }

}

3.2 具体天气目标类

相当于天气预报,能更改天气信息,并通知他的家人(被观察者)

public class ConcreatWeatherSubject extends WeatherSubject {
    private String weatherContent;

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
        //天气更新,通知所有订阅天气的观察者
        this.notifyObservers();
    }
}

3.3 观察者类

相当于他的家人,我们细化了一些细节的信息,如名字,行为等。

public class ConcreatObserver implements Observer {
    //观察者名称
    private String observerName;

    //天气情况
    private String weatherContent;

    //提醒内容
    private String remindThing;

    public String getObserverName() {
        return observerName;
    }

    public void setObserverName(String observerName) {
        this.observerName = observerName;
    }

    public String getWeatherContent() {
        return weatherContent;
    }

    public void setWeatherContent(String weatherContent) {
        this.weatherContent = weatherContent;
    }

    public String getRemindThing() {
        return remindThing;
    }

    public void setRemindThing(String remindThing) {
        this.remindThing = remindThing;
    }

    /**
     * 获取目标类的状态,同步到观察者中
     */
    @Override
    public void update(WeatherSubject subject) {
        weatherContent = ((ConcreatWeatherSubject)subject).getWeatherContent();
        System.out.println(observerName+"收到了"+weatherContent+","+remindThing);
    }

}

这里还可以根据天气情况,判断进行不同的事情。

3.4 测试类

对观察者模式的代码进行一个测试。

public class Client {

    public static void main(String[] args) {
        //1. 创建一个目标
        ConcreatWeatherSubject weatherSubject = new ConcreatWeatherSubject();
        //2. 创建一个观察者
        ConcreatObserver observerGf = new ConcreatObserver();
        observerGf.setObserverName("女票");
        observerGf.setRemindThing("是我们的第一次约会,地点公园");

        ConcreatObserver observerMom = new ConcreatObserver();
        observerMom.setObserverName("老妈");
        observerMom.setRemindThing("去逛街了");
        //3. 注册观察者
        weatherSubject.attach(observerGf);
        weatherSubject.attach(observerMom);
        //4. 目标发布天气
        weatherSubject.setWeatherContent("大暴雨");

    }

}

这时,我们会得到以下的输出。

女票收到了大暴雨,是我们的第一次约会,地点公园
老妈收到了大暴雨,去逛街了

3.5总结

让我们回顾一下整个流程。
首先,我们有我们的主角(目标,被观察者)小陈,和两个他的家人(观察者)。两个家人都去订阅了天气预报的服务。当天气改变时,我们的小陈会依次通知所有的订阅者,订阅者收到通知后,可以自行判断该怎么做。这就是观察者模式。

参考:大话设计模式——观察者模式(一)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值