📜  观察者模式 |第一套(介绍)(1)

📅  最后修改于: 2023-12-03 14:57:21.937000             🧑  作者: Mango

观察者模式 |第一套(介绍)

简介

观察者模式是一种行为型设计模式。在该模式中,对象被称为主题(Subject),它们维护一组观察者(Observers),这些观察者依赖于主题。当主题的状态发生变化时,它会通知所有的观察者。通常,这就是所谓的“发布-订阅”模型。

实现方式

观察者模式由观察者和主题两个角色组成。主题包含一个数组,其中存储着它的观察者。当主题状态发生变化时,它会调用观察者的 update 方法,实现通知。

在观察者模式中,主题和观察者之间是松散耦合的,观察者并不知道主题的具体实现细节。主题只需要提供一个接口,以便观察者可以注册和取消注册,这样它们就可以接收通知了。

应用场景

观察者模式在很多应用场景中都有广泛的应用,比如:

  • MVC框架中,视图分别作为观察者,模型作为主题,当模型的数据发生变化时,通知视图进行更新。
  • 股票市场中,股票作为主题,用户作为观察者,当股票价格发生变化时,通知所有观察者进行更新。
  • 游戏开发中,玩家作为观察者,游戏关卡作为主题,当游戏关卡状态发生变化时,通知所有观察者。
优点和缺点
优点
  • 观察者模式实现了解耦,观察者不需要知道主题的具体实现细节,只需要接受通知即可。
  • 观察者模式支持广播通信,通知所有的观察者。
  • 观察者模式可以支持多个观察者。
缺点
  • 观察者模式可能会引起循环引用,当观察者和主题互相依赖时,可能会造成死循环。
  • 观察者模式有可能会影响系统的性能,尤其是在有大量观察者的情况下,通知所有观察者可能会耗费较长时间。
代码实现

下面是一个简单的观察者模式代码示例:

// 主题接口
interface Subject {
    void registerObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// 观察者接口
interface Observer {
    void update();
}

// 具体主题类
class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();

    @Override
    public void registerObserver(Observer observer) {
        observers.add(observer);
    }

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

    @Override
    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

// 具体观察者类
class ConcreteObserver implements Observer {
    private String name;

    public ConcreteObserver(String name) {
        this.name = name;
    }

    @Override
    public void update() {
        System.out.println(name + ": 接收到通知!");
    }
}

// 测试代码
public class Test {
    public static void main(String[] args) {
        Subject subject = new ConcreteSubject();
        Observer observer1 = new ConcreteObserver("Observer1");
        Observer observer2 = new ConcreteObserver("Observer2");

        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        subject.notifyObservers();

        subject.removeObserver(observer1);

        subject.notifyObservers();
    }
}

在上面的示例中,我们定义了 Subject 接口和 Observer 接口,主题 ConcreteSubject 实现了 Subject 接口,观察者 ConcreteObserver 实现了 Observer 接口。测试代码中,我们注册了两个观察者,并对主题进行了通知操作。另外,我们也演示了如何移除一个观察者。