设计模式之观察者模式

观察者模式是一种行为设计模式, 允许你定义一种订阅机制, 可在对象事件发生时通知多个 “观察” 该对象的其他对象。

解决方案

拥有一些值得关注的状态的对象通常被称为_目标_, 由于它要将自身的状态改变通知给其他对象, 我们也将其称为_发布者_ (publisher)。 所有希望关注发布者状态变化的其他对象被称为_订阅者_ (subscribers)。

观察者模式建议你为发布者类添加订阅机制, 让每个对象都能订阅或取消订阅发布者事件流。 不要害怕! 这并不像听上去那么复杂。 实际上, 该机制包括 1) 一个用于存储订阅者对象引用的列表成员变量; 2) 几个用于添加或删除该列表中订阅者的公有方法。现在, 无论何时发生了重要的发布者事件, 它都要遍历订阅者并调用其对象的特定通知方法。

实际应用中可能会有十几个不同的订阅者类跟踪着同一个发布者类的事件, 你不会希望发布者与所有这些类相耦合的。 此外如果他人会使用发布者类, 那么你甚至可能会对其中的一些类一无所知。因此, 所有订阅者都必须实现同样的接口, 发布者仅通过该接口与订阅者交互。 接口中必须声明通知方法及其参数, 这样发布者在发出通知时还能传递一些上下文数据。

观察者模式结构

1.发布者 (Publisher) 会向其他对象发送值得关注的事件。 事件会在发布者自身状态改变或执行特定行为后发生。 发布者中包含一个允许新订阅者加入和当前订阅者离开列表的订阅构架。

2.当新事件发生时, 发送者会遍历订阅列表并调用每个订阅者对象的通知方法。 该方法是在订阅者接口中声明的。

3.订阅者 (Subscriber) 接口声明了通知接口。 在绝大多数情况下, 该接口仅包含一个 update更新方法。 该方法可以拥有多个参数, 使发布者能在更新时传递事件的详细信息。

4.具体订阅者 (Concrete Subscribers) 可以执行一些操作来回应发布者的通知。 所有具体订阅者类都实现了同样的接口, 因此发布者不需要与具体类相耦合。

5.订阅者通常需要一些上下文信息来正确地处理更新。 因此, 发布者通常会将一些上下文数据作为通知方法的参数进行传递。 发布者也可将自身作为参数进行传递, 使订阅者直接获取所需的数据。

6.客户端 (Client) 会分别创建发布者和订阅者对象, 然后为订阅者注册发布者更新。

Java 示例代码:

import java.util.*;

public class ObserverPattern {

    public static void main(String\[\] args) {

        Subject subjectA = new ConcreteSubject("目标A");

        Observer observerB = new ConcreteObserver("张三", subjectA);

        Observer observerC = new ConcreteObserver("李四", subjectA);

        Observer observerD = new ConcreteObserver("王五", subjectA);

        subjectA.setState("更新了");

        System.out.println("======================================");

        subjectA.Detach(observerD);

        subjectA.setState("停更了");

    }

}

interface Subject { // 目标

    public void Attach(Observer observer); // 添加观察者

    public void Detach(Observer observer); // 删除观察者

    public void Notify(); // 状态改变后 通知所有观察者

    public void setState(String state); // 设置状态(改变状态)

    public String getState(); // 获取状态

}

class ConcreteSubject implements Subject {

    private String name;

    private String state;

    private List<Observer> observerList;

    public ConcreteSubject(String name) {

        state = "未更新";

        this.name = name;

        observerList = new ArrayList<Observer>();

    }

    public void setState(String state) {

        this.state = state;

        System.out.println(name + "的状态发生变化,变化后的状态为:" + state);

        Notify();

    }

    public String getState() {

        return state;

    }

    public void Attach(Observer observer) {

        observerList.add(observer);

    }

    public void Detach(Observer observer) {

        observerList.remove(observer);

    }

    public void Notify() {

        // for (遍历对象类型 对象名 : 遍历对象)

        for (Observer observer : observerList) {

            observer.update();

        }

    }

}

interface Observer { // 观察者接口

    public void update(); // 收到通知 更新观察者的状态

}

class ConcreteObserver implements Observer {

    private String name;

    private String state;

    private Subject subject;

    public ConcreteObserver(String name, Subject subject) {

        this.name = name;

        this.subject = subject;

        subject.Attach(this);

        state = subject.getState();

    }

    @Override

    public void update() {

        System.out.println(name + "收到通知");

        state = subject.getState(); // 让当前观察者的状态 和 改变了状态之后的目标的状态保持一致

        System.out.println(name + "改变后的状态为:" + state);

    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

flysh05

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值