设计模式
设计模式是指在软件开发中,经过验证的,用于解决在特定环境下、重复重现的,特定问题的解决方案。在开发过程中,设计模式不是套用的模板,而是遇到问题时自然而然想到的解决方案,避免了重复造轮子的工作。
模式的基本四要素:
- 模式名称 pattern name
- 问题 problem
- 解决方案 solution
- 效果 consequences
模式的最终目的:高内聚,低耦合 (解耦合)
观察者模式(发布-订阅模式)
发布者subject(目标、主题)、观察者observer(更新方法update)
定义了对象间的一种一对多(变化)的依赖关系,以便当一个对象(subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。推模型——目标对象主动把具体内容广播出去,不管观察者是否需要;拉模型——目标对象通知观察者时,也是主动通知,但是粒度小;如果观察者需要具体信息,需要观察者主动到目标对象中获取(实现:目标通过update方法把目标对象传递给观察者,观察者要获取数据可以通过这个引用来获取)。比如:把subject对象地址给大家,或者只推送摘要,当用户点进去后,才会推送全部内容(拉模型更加常见)。
要点:
- 使用面向对象的抽象, Observer模式使得我们可以独立地改变目标与观察者,从而使二者之间的依赖关系达到松耦合;
- 目标发送通知时,无需指定观察者,通知(可以携带通知信息作为参数)会自动传播;
- 观察者自己决定是否需要订阅通知,目标对象对此一无所知。
实例:报纸的订阅,完成用户注册、服务器推送功能
Subject(订阅者、主题)、Observer(观察者)是抽象类 ConcreteSubject(报纸),ConcreteObserver(读者)是实例
注:url是统一建模语言,类图是其中的一种,包括类名、属性(field) 和方法(method) ,属性/方法名称前的符号表示可见性,+ :表示public, - :表示private,#:表示protected(friendly也归入这类)。
属性的完整表示方式: 可见性 名称 :类型 [ = 缺省值]
方法的完整表示方式: 可见性 名称(参数列表) [ : 返回类型]
类与类之间的关系: 关联(单向、双向、自关联,箭头直线)、聚合(整体与部分,空心菱形+箭头直线)、组合(实心菱形+箭头直线)、依赖(箭头虚线)、继承(空心三角形直线)、接口实现(空心三角形虚线)
#include <iostream>
#include <list>
using namespace std;
class Subject;
class Observer
{
public:
Observer(){}
virtual ~Observer(){}
virtual void update(Subject *subject) = 0;
virtual void update(string content) = 0;
};
class Subject
{
public:
Subject(){}
virtual ~Subject(){}
virtual string getContent() = 0;//获取全文
virtual string getAbstractContent() = 0; //获取摘要
virtual void setContent(string content) = 0;
//订阅主题
void attach(Observer *observer){
observers.push_back(observer);
}
//取消订阅
void detach(Observer *observer){
observers.remove(observer);
}
//通知所有的订阅者
virtual void notifyObservers(){
for(Observer *reader: observers){
// 拉模型(也推送,但粒度小)
reader->update(this);
}
}
virtual void notifyObservers(string content){
for(Observer *reader: observers){
// 推模型
reader->update(content);
}
}
private:
list<Observer *> observers;//保存注册的观察者
};
class Reader : public Observer
{
public:
Reader(){}
virtual ~Reader(){}
virtual void update(Subject *subject){
// 调用对应方法去拉内容
cout << m_name << "收到报纸并阅读,具体内容:" << subj