观察者设计模式

发布于:2024-05-24 ⋅ 阅读:(144) ⋅ 点赞:(0)

观察者模式(Observer Pattern)是一种常见的行为型设计模式,它定义了对象之间的一种一对多的关系,使得一个对象的状态发生变化时,所有依赖于它的对象都能够得到通知并自动更新。

在观察者模式中,有两个重要的角色:Subject(主题)和 Observer(观察者)。Subject 负责维护一个观察者列表,它包含了所有的观察者,并提供了添加和删除观察者的方法。当 Subject 对象的状态发生变化时,它会通知所有的观察者,并调用它们的 update 方法。Observer 对象负责接收 Subject 的通知并进行相应的处理。

观察者模式可以很好地实现松耦合,因为 Subject 和 Observer 之间并没有直接的依赖关系,它们之间的通信通过一个中介对象来完成。同时,观察者模式还支持广播通信,即一个主题对象可以同时向多个观察者对象发送通知。

在 Java 中,观察者模式被广泛地应用于各种 GUI 应用程序的开发中,例如 Swing、JavaFX 等。Java 中的观察者模式通常是通过 Java 提供的 Observer 和 Observable 类来实现的。其中,Observable 类表示主题,Observer 接口表示观察者。通过调用 Observable 对象的 addObserver() 方法来向主题中添加观察者,调用 setChanged() 方法来标记主题状态的变化,调用 notifyObservers() 方法来通知所有的观察者。

  • Subject(主题): 主要由类实现的可观察的接口,通知观察者使用attach方法,以及取消观察的detach方法。
  • ConcreteSubject(具体主题): 是一个实现主题接口的类,处理观察者的变化
  • Observe(观察者): 观察者是一个由对象水岸的接口,根据主题中的更改而进行更新。

先创建一个主题定义,定义添加删除关系以及通知订阅者

public interface Subject {
    // 添加订阅关系
    void attach(Observer observer);
    // 移除订阅关系
    void detach(Observer observer);
    // 通知订阅者
    void notifyObservers(String message);
}

创建的具体主题,并且构建一个容器来维护订阅关系,支持添加删除关系,以及通知订阅者

public class ConcreteSubject implements Subject {

    // 订阅者容器
    private List<Observer> observers = new ArrayList<Observer>();

    @Override
    public void attach(Observer observer) {
        // 添加订阅关系
        observers.add(observer);
    }

    @Override
    public void detach(Observer observer) {
        // 移除订阅关系
        observers.remove(observer);
    }

    @Override
    public void notifyObservers(String message) {
        // 通知订阅者们
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

创建一个观察者接口:

public interface Observer {
    // 处理业务逻辑
    void update(String message);
}
/**
* 最后就是创建具体的观察者类,实现观察者接口的update方法,处理本身的业务逻辑
*/
public class FriendOneObserver implements Observer {

  @Override
    public void update(String message) {
        // 模拟处理业务逻辑
        System.out.println("FriendOne 知道了你发动态了" + message);
    }
}

测试案例

public class test {

    public static void main(String[] args) {

        ConcreteSubject subject = new ConcreteSubject();
        // 这里假设是添加好友
        subject.attach(new FriendOneObserver());
        FriendTwoObserver twoObserver = new FriendTwoObserver();
        subject.attach(twoObserver);

        // 发送朋友圈动态
        subject.notifyObservers("第一个朋友圈消息");
        // 输出结果: FriendOne 知道了你发动态了第一个朋友圈消息
        //          FriendTwo 知道了你发动态了第一个朋友圈消息

        // 这里发现 twoObserver 是个推荐卖茶叶的,删除好友
        subject.detach(twoObserver);
        subject.notifyObservers("第二个朋友圈消息");
        // 输出结果:FriendOne 知道了你发动态了第二个朋友圈消息
    }
}

spring种的设计模式应用:

在Spring中有一个ApplicationListener,也是采用观察者模式来处理的,ApplicationEventMulticaster作为主题,里面有添加,删除,通知等。

状态。在具体观察者中维护一个指向具体目标对象的引用,它存储具体观察者的有关状态,这些状态需要与具体目标保持一致.

观察者模式的优点

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。
  • 被观察者发送通知,所有注册的观察者都会收到信息【可以实现广播机制】

观察者模式的缺点

  • 如果观察者非常多的话,那么所有的观察者收到被观察者发送的通知会耗时比较多
  • 如果被观察者有循环依赖的话,那么被观察者发送通知会使观察者循环调用,会导致系统崩溃

观察者模式常见的使用场景

  • 当一个对象状态的改变需要改变其他对象时。比如,商品库存数量发生变化时,需要通知商品详情页、购物车等系统改变数量。
  • 一个对象发生改变时只想要发送通知,而不需要知道接收者是谁。比如,订阅微信公众号的文章,发送者通过公众号发送,订阅者并不知道哪些用户订阅了公众号。
  • 需要创建一种链式触发机制时。比如,在系统中创建一个触发链, A 对象的行为将影响 B 对象, B 对象的行为将影响 C 对象.…..这样通过观察者模式能够很好地实现。
  • 微博或微信朋友圈发送的场景。这是观察者模式的典型应用场景,一个人发微博或朋友圈,只要是关联的朋友都会收到通知;一旦取消关注,此人以后将不会收到相关通知。

网站公告

今日签到

点亮在社区的每一天
去签到