【设计模式】观察者模式

观察者模式(Observer Pattern)

观察者模式是一种行为设计模式,它定义了一种一对多的依赖关系,使得多个观察者对象能够监听并响应某个主题对象(被观察者)的状态变化。当主题对象的状态发生变化时,所有注册的观察者对象都会自动收到通知并执行相应的更新操作。

一、观察者模式的定义

观察者模式的核心思想是将观察者(Observer)和被观察者(Subject)解耦,使得观察者可以独立于被观察者进行变化。这种模式特别适用于事件驱动的系统,其中对象之间的交互基于事件的发布和订阅机制。

二、观察者模式的结构

观察者模式主要包含以下几个角色:

• 主题(Subject):

• 定义了观察者可以注册和注销的接口。

• 维护一个观察者列表,用于存储所有注册的观察者对象。

• 提供通知机制,当主题的状态发生变化时,通知所有注册的观察者。

• 具体主题(ConcreteSubject):

• 实现主题接口,维护具体的状态信息。

• 当状态发生变化时,调用通知方法,通知所有注册的观察者。

• 观察者(Observer):

• 定义了观察者需要实现的接口,通常包含一个update方法,用于接收主题的通知。

• 具体观察者(ConcreteObserver):

• 实现观察者接口,具体实现update方法,以响应主题的通知。

三、观察者模式的实现

以下是一个简单的实现示例:

1.观察者接口

java 复制代码
public interface Observer {
    void update(String message);
}

2.具体观察者类

java 复制代码
public class ConcreteObserver implements Observer {
    private String name;

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

    @Override
    public void update(String message) {
        System.out.println(name + " received message: " + message);
    }
}

3.主题接口

java 复制代码
import java.util.List;

public interface Subject {
    void registerObserver(Observer observer);
    void unregisterObserver(Observer observer);
    void notifyObservers();
}

4.具体主题类

java 复制代码
import java.util.ArrayList;
import java.util.List;

public class ConcreteSubject implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String state;

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

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

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

    public void setState(String state) {
        this.state = state;
        notifyObservers();
    }
}

5.客户端代码

java 复制代码
public class ObserverPatternDemo {
    public static void main(String[] args) {
        // 创建具体主题
        ConcreteSubject subject = new ConcreteSubject();

        // 创建具体观察者
        Observer observer1 = new ConcreteObserver("Observer 1");
        Observer observer2 = new ConcreteObserver("Observer 2");

        // 注册观察者
        subject.registerObserver(observer1);
        subject.registerObserver(observer2);

        // 改变主题状态
        subject.setState("State 1");

        // 注销一个观察者
        subject.unregisterObserver(observer1);

        // 改变主题状态
        subject.setState("State 2");
    }
}

四、运行效果

运行上述代码后,输出如下:

复制代码
Observer 1 received message: State 1
Observer 2 received message: State 1
Observer 2 received message: State 2

五、观察者模式的优点

• 低耦合性:

• 观察者和被观察者之间是松耦合的,观察者无需了解被观察者的具体实现细节。

• 扩展性:

• 可以动态地增加或减少观察者,而无需修改被观察者的代码。

• 事件驱动:

• 适用于事件驱动的系统,能够有效地实现事件的发布和订阅机制。

六、观察者模式的缺点

• 性能问题:

• 如果观察者数量过多,通知操作可能会变得缓慢,影响性能。

• 顺序问题:

• 观察者接收通知的顺序可能不确定,这在某些情况下可能会导致问题。

• 循环依赖:

• 如果观察者和被观察者之间存在循环依赖,可能会导致死循环。

七、观察者模式的应用场景

• 事件驱动系统:

• 在事件驱动的系统中,观察者模式可以用于实现事件的发布和订阅机制。

• 用户界面:

• 在用户界面中,观察者模式可以用于实现组件之间的交互,例如按钮点击事件。

• 消息传递:

• 在消息传递系统中,观察者模式可以用于实现消息的发布和订阅。

八、总结

观察者模式是一种非常实用的设计模式,通过定义一对多的依赖关系,使得多个观察者能够监听并响应某个主题的状态变化。通过合理使用观察者模式,可以实现低耦合、高扩展性的系统设计,特别适用于事件驱动的系统。

java 复制代码
static class Solution_20250529213945_62384c7db8c842acb9ea7ac804ca8ac9 {
        static public interface Observer {
            void update(String message);
        }

        static public class ConcreteObserver implements Observer {
            private String name;

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

            @Override
            public void update(String message) {
                System.out.println(name + " received message: " + message);
            }
        }

        static public interface Subject {
            void registerObserver(Observer observer);
            void unregisterObserver(Observer observer);
            void notifyObservers();
        }

        static public class ConcreteSubject implements Subject {
            private List<Observer> observers = new ArrayList<>();
            private String state;

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

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

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

            public void setState(String state) {
                this.state = state;
                notifyObservers();
            }
        }

        public static void main(String[] args) {
            // 创建具体主题
            ConcreteSubject subject = new ConcreteSubject();

            // 创建具体观察者
            Observer observer1 = new ConcreteObserver("Observer 1");
            Observer observer2 = new ConcreteObserver("Observer 2");

            // 注册观察者
            subject.registerObserver(observer1);
            subject.registerObserver(observer2);

            // 改变主题状态
            subject.setState("State 1");

            // 注销一个观察者
            subject.unregisterObserver(observer1);

            // 改变主题状态
            subject.setState("State 2");
        }
    }
相关推荐
庄小焱4 小时前
设计模式——原型设计模式(创建型)
设计模式
庄小焱4 小时前
设计模式——适配器设计模式(结构型)
设计模式
TeleostNaCl11 小时前
Windows | 总误按Num Lock?修改注册表永久禁用Numlk键使小键盘一直输入数字
windows·经验分享·电脑
阿巴~阿巴~11 小时前
Git 全平台安装指南:从 Linux 到 Windows 的详细教程
linux·windows·git
摸鱼仙人~11 小时前
Maven 安装与配置指南(适用于 Windows、Linux 和 macOS)
linux·windows·maven
何中应12 小时前
【设计模式-4.6】行为型——状态模式
java·设计模式·状态模式
庄小焱13 小时前
设计模式——抽象工厂设计模式(创建型)
设计模式
庄小焱13 小时前
设计模式——装饰器设计模式(结构型)
设计模式
Dr.多喝热水15 小时前
WPF prism
windows·wpf
向哆哆16 小时前
Java中的设计模式实战:单例、工厂、策略模式的最佳实践
java·设计模式·策略模式