设计模式----观察者模式(C++)

https://www.cnblogs.com/sld6

假设一个数据有三个部分显示数据的, 分别是 max, min,average,我们可以写下这个一个类:

 

复制代码

 

1 class Datashow
2 {
3 public:
4 void measurmentChanged
5 {
6 float temp = getTemplate();
7 float humidity = getHumdity();
8 float pressure = getPressure();
9
10 average.updata(temp, humidity, pressure);
11 max.updata(temp, humidity, pressure);
12 min.updata(tmep, humidity, pressure);
13 }
14 };

复制代码

 

    这样有什么需要改进的吗?

  •     updata 看起来像一个统一的接口
  •     针对具体实现编程了,这样导致了以后增加或删除显示的时候必须修改 dataShow 类

1. 观察者模式

     如果使用观察者模式我们可以这样来理解:

              image

     如图:我们添加观察者4或者删除观察者3 就比较容易了。

    观察者模式定义了对象之间一对多的依赖,这样依赖,当一个对象改变状态时,所有的依赖者都会接收到通知并更新。

    观察者模式提供了一种对象设计,让主题和观察者之间松耦合:

  •       运行时我们用新的观察者取代现有的观察者,主题不会受到影响。
  •       有新类型的观察者出现时,主题代码不需要更改。
  •       可以轻易地独立使用或复用主题或者观察者。
  •       改变主题或者观察者的任何一方都不会影响另一方。

2. uml图

    下面可以看下观察者模式的uml图:

        image

3. 代码实现

    下面是一份C++代码实现

    首先是观察者, 这里实现了三个观察者, average, min, max

 

复制代码

 

1 class Observer
2 {
3 public:
4 virtual void updata(float temperature, float humidity, float pressure) = 0;
5 };
6
7 class Average : public Observer
8 {
9 public:
10 void updata(float temperature, float humidity, float pressure)
11 {
12 cout << (temperature+humidity+pressure)/3 <<endl;
13 }
14 };
15
16 class Min : public Observer
17 {
18 public:
19 void updata(float temperature, float humidity, float pressure)
20 {
21 float tmp = min(temperature,humidity);
22 tmp = min(tmp, pressure);
23
24 cout << tmp <<endl;
25 }
26 };
27
28 class Max : public Observer
29 {
30 void updata(float temperature, float humidity, float pressure)
31 {
32 float tmp = max(temperature,humidity);
33 tmp = max(tmp, pressure);
34
35 cout << tmp <<endl;
36 }
37 };

复制代码

 

然后是主题:

 

复制代码

 

1 class SubjectBase
2 {
3 public:
4 virtual void registerObject(shared_ptr<Observer> observer) = 0;
5 virtual void removeObject(shared_ptr<Observer> observer) = 0;
6 virtual void notifyObject() = 0;
7 };
8
9 class WeatherData : public SubjectBase
10 {
11 public:
12 explicit WeatherData(float temperature, float humidity, float pressure)
13 {
14 temperature_ = temperature;
15 humidity_ = humidity;
16 pressure_ = pressure;
17 }
18
19 void registerObject(shared_ptr<Observer> observer)
20 {
21 observersList_.push_back(observer);
22 //observer->updata(temperature_, humidity_, pressure_);
23 }
24 void removeObject(shared_ptr<Observer> observer)
25 {
26 observersList_.remove(observer);
27 }
28
29 void notifyObject()
30 {
31 for (list<shared_ptr<Observer>>::iterator pos = observersList_.begin();
32 pos != observersList_.end(); ++pos)
33 {
34 (*pos)->updata(temperature_, humidity_, pressure_);
35 }
36 }
37
38 private:
39 list<shared_ptr<Observer>> observersList_;
40 float temperature_;
41 float humidity_;
42 float pressure_;
43 };

复制代码

 

    最后看下如何使用的:

 

复制代码

 

1 int _tmain(int argc, _TCHAR* argv[])
2 {
3 shared_ptr<Observer> observer_1(new Average());
4 shared_ptr<Observer> observer_2(new Min());
5 shared_ptr<Observer> observer_3(new Max());
6 shared_ptr<SubjectBase> subject(new WeatherData(100, 110, 120));
7 subject->registerObject(observer_1);
8 subject->registerObject(observer_2);
9 subject->registerObject(observer_3);
10 subject->notifyObject();
11
12 return 0;
13 }

复制代码

66666/archive/2011/05/25/2057307.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
观察者模式(Observer Pattern)是一种行为型设计模式,它允许一个对象(称为主题或可观察者)在状态变化时通知其他多个对象(称为观察者)。这个模式主要用于解耦主题和观察者,使它们能够独立地进行修改和扩展。 在观察者模式中,主题维护一个观察者列表,可以动态地添加或移除观察者。当主题的状态发生变化时,它会遍历观察者列表,并调用每个观察者的更新方法,将状态变化的信息传递给观察者。观察者可以根据接收到的信息做出相应的操作。 以下是一个简单的示例代码,演示了观察者模式实现: ```c #include <iostream> #include <vector> // 观察者接口 class Observer { public: virtual void update(int data) = 0; }; // 具体观察者 A class ConcreteObserverA : public Observer { public: void update(int data) override { std::cout << "ConcreteObserverA received: " << data << std::endl; } }; // 具体观察者 B class ConcreteObserverB : public Observer { public: void update(int data) override { std::cout << "ConcreteObserverB received: " << data << std::endl; } }; // 主题 class Subject { private: int data; std::vector<Observer*> observers; public: void attach(Observer* observer) { observers.push_back(observer); } void detach(Observer* observer) { // 从观察者列表中删除观察者 // ... } void notify() { for (Observer* observer : observers) { observer->update(data); } } void setData(int value) { data = value; notify(); } }; int main() { Subject subject; ConcreteObserverA observerA; ConcreteObserverB observerB; subject.attach(&observerA); subject.attach(&observerB); subject.setData(42); return 0; } ``` 在上述示例中,`Subject` 是主题类,维护了一个观察者列表。`Observer` 是观察者接口,定义了一个 `update` 方法用于接收主题的通知。`ConcreteObserverA` 和 `ConcreteObserverB` 是具体的观察者类,实现了 `update` 方法。 在 `main` 函数中,我们创建了一个主题对象 `subject` 和两个观察者对象 `observerA` 和 `observerB`。通过调用 `attach` 方法,将观察者对象添加到主题的观察者列表中。然后,通过调用 `setData` 方法改变主题的状态,并自动通知所有观察者。 当 `subject.setData(42)` 被调用时,观察者 `observerA` 和 `observerB` 的 `update` 方法会被依次调用,输出相应的信息。 这就是观察者模式的基本实现。通过使用观察者模式,主题和观察者之间的耦合性降低,可以方便地扩展和修改代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值