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

一、概念

观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。

观察者模式(Observer):定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。结构图如下:
在这里插入图片描述
观察者模式的主要角色如下:

  1. 抽象主题(Subject)角色:也叫抽象目标类,它提供了一个用于保存观察者对象的聚集类和增加、删除观察者对象的方法,以及通知所有观察者的抽象方法。
  2. 具体主题(Concrete Subject)角色:也叫具体目标类,它实现抽象目标中的通知方法,当具体主题的内部状态发生改变时,通知所有注册过的观察者对象。
  3. 抽象观察者(Observer)角色:它是一个抽象类或接口,它包含了一个更新自己的抽象方法,当接到具体主题的更改通知时被调用。
  4. 具体观察者(Concrete Observer)角色:实现抽象观察者中定义的抽象方法,以便在得到目标的更改通知时更新自身的状态。

二、实践

例子:天气观测站和气象报告板的关系。但报告板想获取观测站的数据,可以注册加入到观测站的观察者列表中,这就可以使观测站有数据更新时,自动传给气象报告板。

主题接口

package observe;

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

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

    //更新观察者
    public void notifyObserver();
}

主题实现类:天气各类数据

package observe;
import java.util.ArrayList;

/**
 * 实现Subject
 */
public class WeatherData implements Subject{

    private ArrayList<Observer> observers;  //观察者数组
    private float temp;
    private float humidity;
    private float pressure;

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

    //增加一个观察者
    public void registerObserver(Observer o) {
        observers.add(o);
    }

    //移除一个观察者
    public void removeObserver(Observer o) {
        int i = observers.indexOf(o);
        observers.remove(i);
    }

    //通知观察者
    public void notifyObserver() {
        for (int i = 0; i < observers.size(); i++) {
            Observer observer = observers.get(i);
            observer.update(temp,humidity,pressure);
        }
        System.out.println("更新数据~~~");
    }

    public void measurementChanged(){
        //通知观察者
        notifyObserver();
    }

    // 设置值
    public void setMeasurements(float temp,float humidity,float pressure){
        this.temp = temp;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementChanged();
    }
}

观察者接口:用于更新数据

package observe;

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

展示接口:用于显示数据

package observe;


public interface Display {
    //展示的接口
    public void display();
}

观察者实现类

package observe;

/**
 * 基础的预测值
 */
public class BasicDisplay implements Display,Observer{
    private float temp;
    private float humidity;
    private float pressure;

    public void display() {
        System.out.println("BasicDisplay{" +
                "temp=" + temp +
                ", humidity=" + humidity +
                ", pressure=" + pressure + "}");
    }

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

测试数据

package observe;

/**
 * 测试数据
 */
public class WeatherStation {
    public static void main(String[] args) {
        WeatherData weatherData = new WeatherData();
        BasicDisplay basicDisplay = new BasicDisplay();
        weatherData.registerObserver(basicDisplay);
        weatherData.setMeasurements(1f,2f,3f);
    }
}

三、应用场景

支付场景
在支付场景下,用户购买一件商品,当支付成功之后三方会回调自身,在这个时候系统可能会有很多需要执行的逻辑(如:更新订单状态,发送邮件通知,赠送礼品…),这些逻辑之间并没有强耦合,因此天然适合使用观察者模式去实现这些功能,当有更多的操作时,只需要添加新的观察者就能实现,完美实现了对修改关闭,对扩展开放的开闭原则。
UGC场景
在一个UGC场景下,用户发布的内容往往会经过很多流程,大部分是先发往审核系统,当审核通过之后就会出现一系列的业务逻辑,比如更新内容状态,通知给所有的粉丝等等。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值