当前位置: 首页 > news >正文

深圳专业做网站排名多少钱网站域名后缀区别

深圳专业做网站排名多少钱,网站域名后缀区别,wordpress模板安装,来宾市住房和城乡建设局网站本文内容来源于B站: 【「观察者模式」与「发布/订阅模式」,你分得清楚吗?】 文章目录 观察者模式(Observer Pattern)的代码优化观察者模式 与 发布订阅模式 他们是一样的吗?发布订阅模式总结 我们想象这样一…

本文内容来源于B站:
【「观察者模式」与「发布/订阅模式」,你分得清楚吗?】

文章目录

  • 观察者模式(Observer Pattern)的代码优化
  • 观察者模式 与 发布订阅模式 他们是一样的吗?
    • 发布订阅模式
    • 总结

我们想象这样一个场景:
我们需要开发一个软件系统,该系统可以实时接收某支股票的最新价格,系统可以控制,将这个价格展示在路边的电子广告牌上,同时,坐在控制室中的管理人员可以在显示器上看到这个价格。
当每支股票价格发生变化时,电子广告牌和显示器上的股票价格也要实时变化。

我们首先使用C++来模拟他的一种可能的实现方式:

  • 引入必要的头文件;
  • 创建一个 Monitor 类来表示显示器,其中包含 print 方法来更新显示器的显示内容;
  • 创建一个 Billboard 类来表示广告牌,同样已有 print 方法来进行更新;
  • 创建 Stock 类,该类封装了与股票相关的数据和操作,它包含有一个表示当前股票价格的成员变量 price,以及一个用于更改其值的成员方法 setPrice。
  • 既然 Stock 类是通过 setPrice 来更新股票价格的,那么我们也可以在这里调用 Monitor 和 Billboard 类中的接口来同步更新广告牌和显示器上的数据,所以我们在 Stock 类找那个加入这两个类中的指针,来实现接口的调用。
  • 需要补充的是,我们需要在 Stock 类中初始化这里的两个类指针,让他们指向已经创建好的 Monitor 和 Billboard 类对象。
#include <iostream>
struct Monitor {void print(int v) {std::cout << "Monitor:" << v;}
};
struct Billboard {void display(int v) {std::cout << "Billboard:" << v;}
};
struct Stock {int price = 20;Monitor* monitor;Billboard* billboard;Stock(Monitor* monitor, Billboard* billboard): monitor(monitor), billboard(billboard)void setPrice(int v) {price = v;monitor->print(price);billboard->print(price);}
};

随后我们就可以调用 Stock 对象上的 setPrice 方法来更新股票价格,并且广告牌与显示器上的数字也会被相应更新。

int main () {Monitor monitor;Billboard billboard;Stock stock {&monitor, &billboard};stock.setPrice(10);
}

但是这样的实现方式有许多的问题:

  1. 类之间的紧耦合:Stock 类的稳定性依赖于 Monitor 与 Billboard 类接口的稳定,而当这些接口的名称或使用方式发生变化时,那么 Stock 类就需要被同时修改;并且同样的情况也发生在有更多的显示媒介加入时,比如软件希望同时支持在手机APP上显示最新的股票价格,这个时候我们也需要再次修改 Stock 类。
  2. 这样的紧耦合使得代码的维护成本变得很高,那么如何解决呢?答案就是观察者模式!

观察者模式(Observer Pattern)的代码优化

也就是我们的 Monitor 类和 Billboard 类都是观察者,这里我们可以提供一个统一的父类 Observer ,并且在里面写入 update 接口,这个接口将所有观察者在观测时发生的不同动作进行了统一的包装。Observer 的构造和析构会在后面进行补全:

#include <iostream>
struct Observer {Observer();virtual ~Observer();virtual void update(int) = 0;
}
struct Monitor {void print(int v) {std::cout << "Monitor:" << v;}
};
struct Billboard {void display(int v) {std::cout << "Billboard:" << v;}
};

然后我们的 Monitor 类的构造函数也做相应的修改,然后我们在 Monitor 类中实现父类的 update 接口,Billboard 观察者类也同理,所有观察者都需要将当观测数据发生变化时,可能发生的行为封装在统一的 update(int) 接口中。

struct Monitor {Monitor() : Observer() {}void print(int v) {std::cout << "Monitor:" << v;}void update(int v) override {print(v);}
};
struct Billboard {Billboard() : Observer() {}void display(int v) {std::cout << "Billboard:" << v;}void update(int v) override {display(v);}
};

下面我们把 Stock 类也加入到代码中,我们首先为他提供一个前置声明。接着我们在 Observer 类中加入一个指向 Stock 类对象的指针引用,随后我们改写 Monitor 和 Billboard 类的构造函数,接着我们将之前那段 Stock 类的定义原封不动得放入到代码中。

#include <iostream>struct Stock;struct Observer {Stock* stock;Observer(Stock* stock);virtual ~Observer();virtual void update(int) = 0;
};
struct Monitor {Monitor(Stock* stock) : Observer(stock) {}void print(int v) {std::cout << "Monitor:" << v;}
};
struct Billboard {Billboard(Stock* stock) : Observer(stock) {}void display(int v) {std::cout << "Billboard:" << v;}
};struct Stock {int price = 0;void setPrice(int v) {price = v;}
};

在观察者模式下, Stock 类作为所有观察者关注的对象,它需要支持三个成员方法,notify(int) detach(Observer*) attach(Observer*),这三个方法会围绕 Stock 类内部维护的一个集合进行操作。这个集合中就存放有指向 Oberser 子类对象的指针。这些指针指向的就是所有对 Stock 类感兴趣的观察者对象。

#include list
struct Stock {int price = 0;std::list<Observer*> observerList;void attach(Observer* o) {observerList.push_back(0);}void detach(Observer* o) {observerList.remove(0);}void setPrice(int v) {price = v;}
};

这里我们的 notify(int v) 方法是观察者模式的核心,这个方法会遍历观察者指针容器,并以此调用每个观察者对象上的 update 方法。通过这种方式,Stock 类便能够在状态发生变化时及时通知所有对此感兴趣的观察者对象来进行相应的更新操作,最后我们在 setPrice 方法中调用 notify 方法,这样在股价发生变化时, 能够通知到所有观察者对象。

#include list
struct Stock {int price = 0;std::list<Observer*> observerList;void attach(Observer* o) {observerList.push_back(0);}void detach(Observer* o) {observerList.remove(0);}void notify(int v) {for (auto observer : observerList) {observer->update(v);}}void setPrice(int v) {price = v;notify(v);}
};

下一步我们需要补全 Observer 类的构造函数,让每一个观察者对象在完成构造后,都能被加入到某个 Stock 对象的观察者集合中。而当观察者对象被析构时则从相应的观察者集合中被移除。

Observer::observer(Stock* stk) : stock(stk) {stock->attach(this);
}
Observer::observer(Stock* stk) : stock(stk) {stock->detach(this);
}

最后在 main 函数中我们可以这样来使用这些类:

int main () {Stock stock;Monitor monitor { &stock };Billboard board { &stock };stock.setPrice(10);
}

我们可以看到当 Stock 类在构造时,不再依赖任何观察者对象,因此它的实现可以保持稳定。而观察者对象也可以自由选择观察目标,可以是不同的 Stock 对象,同时不同种类的观察者对象的横向扩展也变得更加灵活

UML类图如上,并且在某些情况下我们可以进一步对观察者模式进行抽象。从而得到另一个版本的 UML 类图和另一个版本的代码实现。

我们为 Stock 类提供了独立的抽象接口 Subject ,从而将 attach、detach 以及 notify 这三个标准接口抽离出来。而 Stock 则保有自己的内部状态,为了保证状态访问的合法性,他们仅能够通过专有的访问器进行访问,下面是对应的 C++ 代码实现:

#include <iostream>
#include <list>struct Observer;
struct Subject {std::list<Observer*> observerList;virtual void attach(Observer* o) = 0;virtual void detach(Observer* o) = 0;virtual void notify() = 0;
};class Stock : public Subject {int price = 0;public:int getPrice();void setPrice(int);void attach(Observer* o) override;void detach(Observer* o) override;void notify() override;
};struct Observer {Subject* sub;Observer(Subject* sub);virtual ~Observer();virtual void update() = 0;
};struct Monitor : Observer {Monitor(Subject* sub) : Observer(sub) {}void print(int v) const { std::cout << "Monitor: " << v << std::endl; }void update() override { print(static_cast<Stock*>(sub)->getPrice()); }
};struct Billboard : Observer {Billboard(Stock* stock) : Observer(stock) {}void display(int v) const { std::cout << "Billboard: " << v << std::endl; }void update() override { display(static_cast<Stock*>(sub)->getPrice()); }
};int Stock::getPrice(void) { return price; }
void Stock::setPrice(int v) {price = v;notify();
}
void Stock::attach(Observer* o) { observerList.push_back(o); }
void Stock::detach(Observer* o) { observerList.remove(0); }
void Stock::notify() {for (auto observer : observerList) {observer->update();}
}Observer::Observer(Subject* sub) : sub(sub) { sub->attach(this); }Observer::~Observer() { sub->detach(this); }int main() {Stock stock;Monitor monitor{&stock};Billboard board{&stock};stock.setPrice(10);
}

观察者模式 与 发布订阅模式 他们是一样的吗?

发布订阅模式

发布订阅模式是一种常用的系统架构模式,他用来规定一个系统中的不同部分之间应该如何进行消息传递。

在这个模式中,发布者可以是系统中的消息服务、事件服务;而订阅者可以是系统中的其他服务,比如网关服务、路由服务等等。

发布者与订阅者之间互相不知道对方的存在,他们之间通过名为消息代理的部分连接起来。发布者会向消息代理发送不同类型的消息,比如一个系统通知、一个发生的事件。而订阅者则会与消息代理通信,选择自己想要订阅的消息类型。

在之后的流程中,每当消息代理接收到符合要求的消息,便会把他们直接转发给相应的订阅者进行处理;这便是发布订阅模式的基本形式。

总结

所以综合来看,我们可以得出这样的结论:

http://www.yayakq.cn/news/641065/

相关文章:

  • 优秀的网站建设自己做的网站怎么实现结算功能
  • 做一个跨境电商网站建网站的软件 优帮云
  • 网站免费建站众享星球广告设计与制作需要学什么专业
  • 做网站微信公众号西安工程建设信息网站
  • 推荐做流程图的网站百度公司全称
  • pc网站建设怎么做网站建设中存在的问题
  • 网站深圳网站升级应注意的问题
  • 京东网站哪个公司做的越秀金融大厦北塔
  • 在线建设网站制作腾讯网页游戏平台
  • 国外建站 网站 推荐wordpress支持多少字
  • 助农网站策划书页面跳转不了
  • 湖南官网网站推广软件wordpress 地图菜单
  • 什么网站可以做任务领赏金wordpress app 服务端
  • 个人资料库网站怎么做宁波seo教程app推广
  • 百度网站优化公司为什么做这个网站反馈问题
  • 天门市住房和城乡建设局网站山西网站开发建设
  • 静态网站建设实训报告深圳市房地产信息系统平台
  • 北京建网站的做网站空间费用是什么意思
  • 怎么弄一个网站平台展示网站多少钱一个
  • 网站集约化建设存在的困难百度搜索网站带图片
  • 如何建设网站兴田德润可信赖部署wordpress
  • 网站开发建设费用广州网站建设出名 乐云践新
  • 个人可否建立网站青浦网站建设
  • 河南网站制作工作室苏州网络推广公司哪家好
  • 深圳房地产网站开发网站制作专业的公司有哪些
  • 海南省住房与城乡建设厅网站云南房产网站建设
  • 工信部网站icp备案查询校园文化网站建设
  • 上蔡县住房和城乡建设局网站做电子签章登录哪个网站
  • 招聘网站比对表怎么做网页游戏4399
  • wordpress 视频站模版百度收录刷排名