首页 > 其他分享 >软件设计模式系列之二十一——观察者模式

软件设计模式系列之二十一——观察者模式

时间:2023-10-01 19:44:08浏览次数:36  
标签:软件设计 通知 void 主题 观察者 模式 对象

1 观察者模式的定义

观察者模式(Observer Pattern)是一种行为型设计模式,它允许对象之间建立一对多的依赖关系,当一个对象的状态发生变化时,所有依赖于它的对象都会得到通知并自动更新。这个模式也被称为发布-订阅模式,因为它模拟了一个主题(发布者)与多个观察者(订阅者)之间的关系。

观察者模式主要用于实现对象之间的解耦,使得被观察者(主题)和观察者之间的交互更加灵活。它是一种广泛应用于软件开发中的设计模式,常见于图形界面开发、事件处理系统和分布式系统中。

2 举例说明

为了更好地理解观察者模式,让我们考虑一个实际的例子:天气站。假设我们有一个天气站应用程序,用户可以订阅该应用程序以获取实时天气更新。在这个场景中,天气站就是被观察者(主题),而订阅天气更新的用户就是观察者(订阅者)。

当天气站收到新的天气数据时,它会通知所有订阅者,以便它们可以更新显示当前天气的界面。这种方式使得用户可以实时获取最新的天气信息,而无需反复查询。

3 结构

观察者模式的结构包括以下几个要素:

Subject(主题):主题是被观察的对象,它维护一组观察者,提供方法来添加和删除观察者,并在状态发生变化时通知观察者。
ConcreteSubject(具体主题):具体主题是主题的具体实现,它包含了真正的状态和状态变化逻辑。
Observer(观察者):观察者是订阅主题的对象,它定义了一个更新接口,以便主题在状态变化时通知观察者。
ConcreteObserver(具体观察者):具体观察者是观察者的具体实现,它实现了更新接口,以便在接收到通知时执行相应的操作。

4 实现步骤

观察者模式的实现步骤如下:

创建主题接口(Subject),定义添加、删除和通知观察者的方法。
创建具体主题类(ConcreteSubject),实现主题接口,并维护观察者列表和状态变量。
创建观察者接口(Observer),定义更新方法。
创建具体观察者类(ConcreteObserver),实现观察者接口,并定义具体的更新逻辑。
在客户端中创建主题对象和观察者对象,将观察者注册到主题上。
当主题的状态发生变化时,调用主题的通知方法,通知所有注册的观察者。
观察者接收到通知后,执行相应的更新操作。

5 代码实现(Java)

让我们通过一个简单的 Java 代码示例来演示观察者模式的实现。

// Step 1: 创建主题接口
interface Subject {
    void addObserver(Observer observer);
    void removeObserver(Observer observer);
    void notifyObservers();
}

// Step 2: 创建具体主题类
class WeatherStation implements Subject {
    private List<Observer> observers = new ArrayList<>();
    private String weatherData;

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

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

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

    public void setWeatherData(String data) {
        this.weatherData = data;
        notifyObservers();
    }
}

// Step 3: 创建观察者接口
interface Observer {
    void update(String data);
}

// Step 4: 创建具体观察者类
class User implements Observer {
    private String name;

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

    @Override
    public void update(String data) {
        System.out.println(name + " 收到天气更新:" + data);
    }
}

// Step 5: 客户端代码
public class Main {
    public static void main(String[] args) {
        WeatherStation weatherStation = new WeatherStation();

        User user1 = new User("Alice");
        User user2 = new User("Bob");

        weatherStation.addObserver(user1);
        weatherStation.addObserver(user2);

        weatherStation.setWeatherData("晴天");
        weatherStation.setWeatherData("下雨");
    }
}

在上面的示例中,WeatherStation 是具体主题,User 是具体观察者。当天气发生变化时,WeatherStation 通知所有注册的观察者,观察者执行相应的更新操作。

6 典型应用场景

观察者模式在许多应用场景中都得到了广泛的应用,包括以下一些场景:

股票市场:投资者可以订阅股票价格的变化。一旦股票价格发生变化,所有订阅了该股票的投资者都会立即收到通知,以便他们可以做出及时的投资决策。

社交媒体:社交媒体平台中,用户可以关注其他用户的动态。当被关注用户发布新的动态、照片或视频时,关注者会收到通知,以便互动和评论。

库存管理:在库存管理系统中,订阅者可以订阅特定商品的库存变化。当库存数量发生变化时,订阅者可以收到通知,帮助他们及时补充库存或采取其他措施。

观察者模式将主题和观察者解耦,使主题可以轻松通知多个观察者,而观察者可以根据自己的需求选择订阅感兴趣的主题。这种模式提高了系统的灵活性和可扩展性,使信息传递更加高效和及时

7 优缺点

观察者模式的优点包括:

解耦性:被观察者和观察者之间的关系是松散耦合的,可以独立地改变它们中的任何一个,而不会影响其他部分。
可扩展性:可以轻松地添加新的观察者,扩展系统功能。
通知机制:观察者能够实时获取到被观察者的状态变化,无需主动轮询。
可维护性:代码易于维护和理解,因为逻辑分散在各个观察者中。

观察者模式的缺点包括:

如果观察者过多,通知所有观察者可能会导致性能问题。
如果观察者之间有依赖关系,可能会引入复杂性。
如果不正确地实现,可能会导致循环引用。

8 类似模式

观察者模式建立了一种一对多的依赖关系,其中一个对象(被观察者)维护一组依赖它的对象(观察者),并在状态变化时通知观察者。与观察者模式类似的模式有以下几种,它们在某些方面具有相似性,但也存在一些区别:

委托模式(Delegate Pattern):

委托模式也允许一个对象委托给多个对象,类似于观察者模式中的通知多个观察者。 在委托模式中,被委托的对象通常不知道委托它的对象,而观察者模式中,被观察者知道它的观察者并主动通知它们。委托模式通常用于事件处理和回调机制,而观察者模式用于状态变化通知。

策略模式(Strategy Pattern):

策略模式和观察者模式都关注对象之间的交互,但在策略模式中,可以根据需要切换不同的算法或行为,而观察者模式关注对象状态的变化通知。观察者模式通常用于对象之间的一对多关系,而策略模式用于定义一组可互换的算法,客户端可以在运行时选择其中一个算法。

命令模式(Command Pattern):

命令模式和观察者模式都涉及到将请求发送给接收者对象,但观察者模式关注状态变化的通知,而命令模式关注封装请求成对象。在观察者模式中,被观察者通知观察者状态的改变,而在命令模式中,客户端创建命令对象并将其发送给接收者,接收者执行命令。

这些模式都有共同点,即它们都有助于降低对象之间的耦合度,并提供了一种松散的交互方式。然而,它们的重点和用途有所不同,因此在设计应用程序时,需要根据具体需求选择最合适的模式。

9 小结

观察者模式是一种有用的设计模式,它可以帮助我们实现对象之间的松散耦合,使系统更加灵活和可扩展。通过定义一对多的依赖关系,观察者模式允许被观察者在状态变化时通知所有观察者,实现了一种高效的通知机制。在实际应用中,观察者模式可以用于各种领域,包括图形界面开发、事件处理系统、消息队列和实时数据更新等。要成功使用观察者模式,需要谨慎设计接口和类,并确保正确地管理观察者的注册和通知。

标签:软件设计,通知,void,主题,观察者,模式,对象
From: https://www.cnblogs.com/coodream2009/p/17739177.html

相关文章

  • dpvs dnat模式
    dnat模式发送报文src/ipvs/ip_vs_core.c针对ipv4,INET_HOOK_PRE_ROUTING注册2个函数dp_vs_pre_routing和dp_vs_in,因为nat不做防止DDos攻击的syn_proxy,所以看dp_vs_in。conn_sched新请求建立连接选择后端rs建立连接,支持tcp、udp和icmp。dp_vs_schedule->dp_vs_conn_new->dp_vs_c......
  • 单例模式
    什么是单例模式单例模式是指在内存中只会创建且仅创建一次对象的设计模式。在程序中多次使用同一个对象且作用相同时,为了防止频繁地创建对象使得内存飙升,单例模式可以让程序仅在内存中创建一个对象,让所有需要调用的地方都共享这一单例对象。单例模式的类型懒汉式:在真正......
  • 【11.0】Fastapi的OAuth2.0的授权模式
    【一】OAuth2.0的授权模式授权码授权模式(AuthorizationCodeGrant)隐式授权模式(ImplicitGrant)密码授权模式(ResourceOwnerPasswordCredentialsGrant)客户端凭证授权模式(ClientCredentialsGrant)【二】密码授权模式【1】FastAPI的OAuth2PasswordBearer说明......
  • java 实现外观模式
    外观模式(FacadePattern)是一种结构型设计模式,它提供了一个简化的接口,用于访问一组相关的接口或子系统。外观模式的主要目的是隐藏复杂的系统结构,提供一个更简单的接口供客户端使用。以下是一个简单的Java示例,演示如何实现外观模式:首先,假设我们有一个音响系统,它包含了多个子系统,如音......
  • java 实现模板方法模式
    模板方法模式(TemplateMethodPattern)是一种行为型设计模式,它定义了一个算法的骨架,将具体的步骤延迟到子类中实现。模板方法模式使得子类可以重新定义算法的某些步骤,而不改变算法的结构。以下是一个简单的Java示例,演示如何实现模板方法模式:首先,定义一个抽象类Game,它包含一个模板方......
  • 访问者模式
    访问者模式案例引入要求1.将观众分为男生和女生,对歌手进行评价,当看完某个歌手表演后,对于歌手有不同的评价(评价的类别,有成功,失败等)。传统方式实现思路创建一个Person类,其有两个子类,分别是Man和WoMan,使用ifelse分支,去判断一个歌手的评价,成功对应成功分支,失败对应失败分支。......
  • java中观察者模式的简单实现
    4要素:1观察者接口2具体的观察者3管理者接口4管理者实现类5调用1观察者接口包含观察者行为方法publicinterfaceObserver{/***当目标类发生变化时所执行的操作**/StringdoSomething();}2具体的观察者//具体观察者A@Slf4j@Component("ObserverA")pu......
  • java实现策略模式
    策略模式(StrategyPattern)是一种行为型设计模式,它定义了一系列算法,将每个算法封装成单独的类,并使它们可以相互替换,以使算法的变化独立于客户端使用算法的方式。策略模式允许客户端选择不同的算法,以满足不同的需求。以下是一个简单的Java示例,演示如何实现策略模式:首先,定义一个策略接......
  • java实现观察者模式
    观察者模式(ObserverPattern)是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生变化时,它的所有依赖者(观察者)都会收到通知并自动更新。观察者模式通常包括以下角色:主题(Subject)、观察者(Observer)、具体主题(ConcreteSubject)和具体观察者(ConcreteObserver)。以下是一......
  • java实现迭代器模式
    迭代器模式(IteratorPattern)是一种行为型设计模式,它提供一种方法来顺序访问一个聚合对象(如列表、集合、数组等)中的元素,而不暴露聚合对象的内部表示。迭代器模式通常包括以下角色:迭代器(Iterator)、具体迭代器(ConcreteIterator)、聚合(Aggregate)、具体聚合(ConcreteAggregate)。以下是一......