设计模式——14. 观察者模式

这篇具有很好参考价值的文章主要介绍了设计模式——14. 观察者模式。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1. 说明

观察者模式(Observer Pattern)是一种行为型设计模式,用于定义对象之间的一对多依赖关系,使得当一个对象的状态发生改变时,所有依赖于它的对象都能够自动收到通知并更新自己的状态,以保持与被观察对象的同步。观察者模式也被称为发布-订阅模式。

观察者模式包含以下关键角色:

  1. Subject(被观察者):Subject 是被观察对象,它维护一组观察者对象,并提供方法来添加、删除和通知观察者。当 Subject 的状态发生改变时,它会通知所有注册的观察者。
  2. Observer(观察者):Observer 是观察者对象,它定义了一个更新方法(通常命名为 update),用于接收被观察对象的通知并执行相应的操作。多个观察者可以订阅同一个被观察者。
  3. ConcreteSubject(具体被观察者):ConcreteSubject 是具体的被观察对象,它实现了 Subject 接口,负责维护状态并在状态发生改变时通知观察者。
  4. ConcreteObserver(具体观察者):ConcreteObserver 是具体的观察者对象,它实现了 Observer 接口,并定义了在接收到通知时要执行的具体操作。

观察者模式的优点包括:

  • 解耦性:被观察者和观察者之间的关系是松散耦合的,它们可以独立变化,不会相互影响。
  • 可扩展性:可以方便地添加新的观察者,无需修改被观察者的代码。
  • 通知机制:当被观察者的状态发生改变时,所有注册的观察者会自动收到通知,不需要手动轮询。

观察者模式是一种非常有用的模式,它可以帮助实现对象之间的松散耦合,提高系统的可维护性和可扩展性。

2. 使用的场景

观察者模式在以下情况下特别有用,这些场景通常涉及到对象之间的状态变化需要通知其他对象或组件:

  1. 事件处理和 GUI 开发: 在图形用户界面(GUI)应用程序中,用户交互和事件处理是观察者模式的经典用例。例如,按钮点击事件、窗口关闭事件、鼠标移动事件等都可以通过观察者模式来处理。
  2. 消息通知系统: 观察者模式用于构建发布-订阅模型的消息通知系统,例如电子邮件通知、新闻订阅、社交媒体通知等。当有新消息或更新时,通知系统会通知所有订阅者。
  3. 股票市场和金融领域: 在股票市场中,股票价格的变化会通知所有订阅该股票的投资者。金融领域中也有类似的应用,如外汇汇率变化通知。
  4. 分布式系统: 在分布式系统中,观察者模式可以用于实现事件驱动的通信机制。当一个节点的状态发生变化时,可以通知其他节点或服务。
  5. 日志记录和监控系统: 观察者模式可以用于监控系统中,例如服务器日志记录和性能监控。当系统状态或日志条目发生变化时,观察者可以记录或报警。
  6. 实时数据更新: 当需要在多个地方保持数据同步时,观察者模式可以用于实时数据更新,确保所有订阅者都能及时获得最新数据。
  7. 游戏开发: 在游戏开发中,观察者模式常用于处理游戏中的事件和状态变化,如角色状态变化、敌人出现等。

总之,观察者模式适用于任何需要对象之间的松散耦合、动态通信和状态同步的场景。它有助于将系统组件分离,提高代码的可维护性和可扩展性,并使系统更容易适应变化。

3. 应用例子

以下是一个使用 Python 实现的观察者模式示例,模拟了一个简单的股票市场通知系统:

# 定义观察者接口
class Observer:
    def update(self, message):
        pass

# 定义具体观察者类
class StockInvestor(Observer):
    def __init__(self, name):
        self.name = name

    def update(self, message):
        print(f"{self.name} 收到股票市场通知:{message}")

# 定义被观察者类
class StockMarket:
    def __init__(self):
        self.investors = []  # 存储观察者

    def add_investor(self, investor):
        self.investors.append(investor)

    def remove_investor(self, investor):
        self.investors.remove(investor)

    def notify_investors(self, message):
        for investor in self.investors:
            investor.update(message)

if __name__ == "__main__":
    # 创建被观察者对象
    stock_market = StockMarket()

    # 创建具体观察者并注册到被观察者
    investor1 = StockInvestor("投资者1")
    investor2 = StockInvestor("投资者2")

    stock_market.add_investor(investor1)
    stock_market.add_investor(investor2)

    # 发送通知给观察者
    stock_market.notify_investors("股票价格上涨!")

    # 移除一个观察者
    stock_market.remove_investor(investor2)

    # 再次发送通知给观察者
    stock_market.notify_investors("股票价格下跌!")

4. 实现要素

观察者模式的实现要素包括以下几个部分:

  1. Subject(被观察者): 被观察者是一个具体的对象,它维护一组观察者对象的引用,提供方法用于添加、删除和通知观察者。通常,被观察者会维护一个状态,当状态发生变化时,会通知所有观察者。
  2. Observer(观察者): 观察者是一个接口或抽象类,定义了一个更新方法(通常命名为 update),该方法在被观察者状态发生变化时被调用。具体的观察者类实现该接口,以便接收被观察者的通知并执行相应的操作。
  3. ConcreteSubject(具体被观察者): 具体被观察者是被观察者接口的实现类,它负责维护状态并在状态发生改变时通知观察者。通常,具体被观察者会维护一个观察者列表,用于存储注册的观察者。
  4. ConcreteObserver(具体观察者): 具体观察者是观察者接口的实现类,它定义了在接收到通知时要执行的具体操作。每个具体观察者都可以有不同的实现。

5. UML图

设计模式——14. 观察者模式,设计模式大全,设计模式,观察者模式,java,python,golang,c++,javascript

  • Subject 接口定义了 attach(添加观察者)、detach(删除观察者)和 notify(通知观察者)等方法。
  • ConcreteSubject 类实现了 Subject 接口,它维护了一个观察者列表,并在状态发生变化时调用 notify 方法通知观察者。
  • Observer 接口定义了 update 方法,用于在被观察者状态发生变化时接收通知。
  • ConcreteObserver 类实现了 Observer 接口,它包含具体的操作逻辑,以响应被观察者的通知。

观察者模式的关键思想是被观察者与观察者之间的松散耦合,被观察者不需要知道观察者的具体实现,只需要知道它们实现了共同的接口。这种松散耦合使得系统更易于扩展和维护,符合面向对象设计原则中的依赖倒置原则。

6. Java/golang/javascrip/C++ 等语言实现方式

6.1 Java实现

上述例子用Java语言实现示例如下:

import java.util.ArrayList;
import java.util.List;

// 定义观察者接口
interface Observer {
    void update(String message);
}

// 定义具体观察者类
class StockInvestor implements Observer {
    private String name;

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

    @Override
    public void update(String message) {
        System.out.println(name + " 收到股票市场通知:" + message);
    }
}

// 定义被观察者类
class StockMarket {
    private List<Observer> investors = new ArrayList<>();

    public void addInvestor(Observer investor) {
        investors.add(investor);
    }

    public void removeInvestor(Observer investor) {
        investors.remove(investor);
    }

    public void notifyInvestors(String message) {
        for (Observer investor : investors) {
            investor.update(message);
        }
    }
}

public class ObserverPatternExample {
    public static void main(String[] args) {
        // 创建被观察者对象
        StockMarket stockMarket = new StockMarket();

        // 创建具体观察者并注册到被观察者
        Observer investor1 = new StockInvestor("投资者1");
        Observer investor2 = new StockInvestor("投资者2");

        stockMarket.addInvestor(investor1);
        stockMarket.addInvestor(investor2);

        // 发送通知给观察者
        stockMarket.notifyInvestors("股票价格上涨!");

        // 移除一个观察者
        stockMarket.removeInvestor(investor2);

        // 再次发送通知给观察者
        stockMarket.notifyInvestors("股票价格下跌!");
    }
}

6.2 Golang实现

上述例子用golang实现示例如下:

package main

import "fmt"

// 定义观察者接口
type Observer interface {
        Update(message string)
}

// 定义具体观察者结构体
type StockInvestor struct {
        Name string
}

func (si *StockInvestor) Update(message string) {
        fmt.Printf("%s 收到股票市场通知:%s\n", si.Name, message)
}

// 定义被观察者结构体
type StockMarket struct {
        investors []Observer
}

func (sm *StockMarket) AddInvestor(investor Observer) {
        sm.investors = append(sm.investors, investor)
}

func (sm *StockMarket) RemoveInvestor(investor Observer) {
        for i, obs := range sm.investors {
                if obs == investor {
                        sm.investors = append(sm.investors[:i], sm.investors[i+1:]...)
                        break
                }
        }
}

func (sm *StockMarket) NotifyInvestors(message string) {
        for _, investor := range sm.investors {
                investor.Update(message)
        }
}

func main() {
        // 创建被观察者对象
        stockMarket := &StockMarket{}

        // 创建具体观察者并注册到被观察者
        investor1 := &StockInvestor{Name: "投资者1"}
        investor2 := &StockInvestor{Name: "投资者2"}

        stockMarket.AddInvestor(investor1)
        stockMarket.AddInvestor(investor2)

        // 发送通知给观察者
        stockMarket.NotifyInvestors("股票价格上涨!")

        // 移除一个观察者
        stockMarket.RemoveInvestor(investor2)

        // 再次发送通知给观察者
        stockMarket.NotifyInvestors("股票价格下跌!")
}

6.3 Javascript实现

上述例子用javascript实现示例如下:

// 定义观察者接口
class Observer {
  update(message) {}
}

// 定义具体观察者类
class StockInvestor extends Observer {
  constructor(name) {
    super();
    this.name = name;
  }

  update(message) {
    console.log(`${this.name} 收到股票市场通知:${message}`);
  }
}

// 定义被观察者类
class StockMarket {
  constructor() {
    this.investors = [];
  }

  addInvestor(investor) {
    this.investors.push(investor);
  }

  removeInvestor(investor) {
    const index = this.investors.indexOf(investor);
    if (index !== -1) {
      this.investors.splice(index, 1);
    }
  }

  notifyInvestors(message) {
    this.investors.forEach((investor) => {
      investor.update(message);
    });
  }
}

// 创建被观察者对象
const stockMarket = new StockMarket();

// 创建具体观察者并注册到被观察者
const investor1 = new StockInvestor("投资者1");
const investor2 = new StockInvestor("投资者2");

stockMarket.addInvestor(investor1);
stockMarket.addInvestor(investor2);

// 发送通知给观察者
stockMarket.notifyInvestors("股票价格上涨!");

// 移除一个观察者
stockMarket.removeInvestor(investor2);

// 再次发送通知给观察者
stockMarket.notifyInvestors("股票价格下跌!");

6.4 C++实现

上述例子用C++实现如下:

#include <iostream>
#include <vector>

// 定义观察者基类
class Observer {
public:
    virtual void update(const std::string& message) = 0;
};

// 定义具体观察者类
class StockInvestor : public Observer {
public:
    StockInvestor(const std::string& name) : name(name) {}

    void update(const std::string& message) override {
        std::cout << name << " 收到股票市场通知:" << message << std::endl;
    }

private:
    std::string name;
};

// 定义被观察者类
class StockMarket {
public:
    void addInvestor(Observer* investor) {
        investors.push_back(investor);
    }

    void removeInvestor(Observer* investor) {
        for (auto it = investors.begin(); it != investors.end(); ++it) {
            if (*it == investor) {
                investors.erase(it);
                break;
            }
        }
    }

    void notifyInvestors(const std::string& message) {
        for (auto investor : investors) {
            investor->update(message);
        }
    }

private:
    std::vector<Observer*> investors;
};

int main() {
    // 创建被观察者对象
    StockMarket stockMarket;

    // 创建具体观察者并注册到被观察者
    StockInvestor investor1("投资者1");
    StockInvestor investor2("投资者2");

    stockMarket.addInvestor(&investor1);
    stockMarket.addInvestor(&investor2);

    // 发送通知给观察者
    stockMarket.notifyInvestors("股票价格上涨!");

    // 移除一个观察者
    stockMarket.removeInvestor(&investor2);

    // 再次发送通知给观察者
    stockMarket.notifyInvestors("股票价格下跌!");

    return 0;
}

7. 练习题

假设你正在开发一个简单的天气应用程序,用户可以订阅并接收天气预报通知。设计一个观察者模式来实现这个应用程序。

要求:

  1. 创建一个 WeatherData 类,作为被观察者,它可以存储当前的天气信息(例如温度、湿度、气压)。
  2. 创建一个 Observer 接口,定义一个 update 方法,以便观察者可以在天气信息变化时收到通知。
  3. 创建具体观察者类 CurrentConditionsDisplay,它实现了 Observer 接口,可以显示当前的温度、湿度和气压。
  4. 在 WeatherData 类中,实现注册观察者、移除观察者和通知观察者的方法。
  5. 编写一个测试程序,创建一个 WeatherData 对象和一个 CurrentConditionsDisplay 对象,然后模拟天气信息的变化,观察 CurrentConditionsDisplay 是否能够接收并显示最新的天气信息。

你可以在评论区里或者私信我回复您的答案,这样我或者大家都能帮你解答,期待着你的回复~文章来源地址https://www.toymoban.com/news/detail-726419.html

到了这里,关于设计模式——14. 观察者模式的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 设计模式——观察者模式

    观察者模式可以分为观察者和被观察者,观察者通过注册到一个被观察者中,也可视为订阅,当被观察者的数据发生改变时,会通知到观察者,观察者可以据此做出反应。 可以类比订阅报纸,报社就是被观察者,订阅者就是观察者,订阅者通过订阅报纸与报社建立联系,而报

    2024年02月15日
    浏览(38)
  • 设计模式-观察者模式

    观察者模式是一种行为型设计模式,它定义了一种一对多的依赖关系,当一个对象的状态发生改变时,其所有依赖者都会收到通知并自动更新。当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。比如,当一个对象被修改时,则会自动通知依赖它的对象。观察者

    2024年02月15日
    浏览(43)
  • 设计模式之观察者模式

    可以帮你的对象知悉现况,不会错过该对象感兴趣的事。对象甚至在运行时可决定是否要继续被通知。 从报纸和杂志的订阅说起: 报社的业务就是出版报纸 向某家报社订阅报纸,只要他们有新报纸出版,就会给你送来。只要你是他们的订户,你就会一直收到新报纸。 当你不

    2024年01月24日
    浏览(41)
  • 重温设计模式 --- 观察者模式

    观察者模式 是一种行为型设计模式,它允许对象之间建立一种一对多的关系,使得当一个对象状态改变时,所有依赖它的对象都能够自动得到通知并更新自己的状态。该模式可以帮助我们实现松耦合的系统,以便更好地应对变化和扩展。 在观察者模式中,有两个角色: 观察

    2024年02月13日
    浏览(43)
  • 设计模式(11)观察者模式

    一、概述: 1、定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。 2、结构图: 实现  调用

    2024年02月11日
    浏览(36)
  • 设计模式-观察者

    观察者模式是一种广泛应用于软件开发中的行为设计模式,尤其是在面向对象编程(OOP)中。该模式定义了对象之间的一对多依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新 在观察者模式中,存在两个主要角色: 主题(Subject) 或 被

    2024年01月22日
    浏览(33)
  • 观察者设计模式

    行为型模式(Behavioral Patterns):这类模式主要关注对象之间的通信。它们 分别是: 职责链模式(Chain of Responsibility) 命令模式(Command) 解释器模式(Interpreter) 迭代器模式(Iterator) 中介者模式(Mediator) 备忘录模式(Memento) 观察者模式(Observer) 状态模式(State) 策略

    2024年01月24日
    浏览(35)
  • 设计模式:行为型模式 - 观察者模式

    定义: 又被称为发布-订阅(Publish/Subscribe)模式,它定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态变化时,会通知所有的观察者对象,使他们能够自动更新自己。 在观察者模式中有如下角色: Subject:抽象主题(抽象被观察

    2023年04月22日
    浏览(84)
  • 设计模式【行为型】-- 观察者模式

    观察者模式(Observer Pattern)是一种行为型设计模式,用于在对象之间建立一种一对多的依赖关系,使得当一个对象状态改变时,其相关依赖对象都能得到通知并自动更新。 主题( Subject ):也称为被观察者,它维护一个观察者列表,并提供添加、删除和通知观察者的方法。

    2024年02月15日
    浏览(40)
  • js设计模式:观察者模式

    和发布订阅模式基本类似。 当某一对象状态发生变化时,所有的观察者都会收到通知。 vue响应式原理就是很经典的案例,数据发生变化,通知各个依赖。

    2024年02月19日
    浏览(20)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包