先看该常规的没有委托概念的代码,如下:
#include
#include
#include
using namespace std;
class Subject; // 前向声明
// 抽象观察者
class Observer
{
protected:
string name;
Subject *sub;
public:
Observer(string name, Subject *sub)
{
this->name = name;
this->sub = sub;
}
virtual void update() = 0;
};
// 抽象通知者
class Subject
{
protected:
list<Observer *> observers;
public:
string event;
virtual void attach(Observer *) = 0;
virtual void detach(Observer *) = 0;
virtual void notify() = 0;
};
// 具体通知者,秘书
class Secretary : public Subject
{
void attach(Observer *observer) override
{
observers.push_back(observer);
}
void detach(Observer *observer) override
{
list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
if ((*iter) == observer)
{
observers.erase(iter);
}
++iter;
}
}
void notify() override
{
list<Observer *>::iterator iter = observers.begin();
while (iter != observers.end())
{
(*iter)->update();
++iter;
}
}
};
// 具体的观察者,看股票的
class StockObserver : public Observer
{
public:
StockObserver(string name, Subject *sub) : Observer(name, sub)
{
}
void update() override
{
cout << name << " 收到消息:" << sub->event << endl;
if (sub->event == "梁所长来了!")
{
cout << "我马上关闭股票,装做很认真工作的样子!" << endl;
}
}
};
// 具体的观察者,看NBA的
class NBAObserver : public Observer
{
public:
NBAObserver(string name, Subject *sub) : Observer(name, sub)
{
}
void update() override
{
cout << name << " 收到消息:" << sub->event << endl;
if (sub->event == "梁所长来了!")
{
cout << "我马上关闭NBA,装做很认真工作的样子!" << endl;
}
}
};
int main()
{
// 创建通知者
Subject *dwq = new Secretary();
// 被观察的对象
Observer *xs = new NBAObserver("xiaoshuai", dwq);
Observer *lm = new StockObserver("limin", dwq);
// 加入观察队列
dwq->attach(xs);
dwq->attach(lm);
// 事件
dwq->event = "去吃饭了!";
// 通知
dwq->notify();
cout << endl;
// 事件
dwq->event = "梁所长来了!";
// 通知
dwq->notify();
cout << endl;
return 0;
}
委托是一种设计原则,指的是一个对象(委托者)将自身的一部分职责或功能交由另一个对象(被委托者)来执行。这种机制允许对象专注于自己的核心功能,同时利用外部对象的专业能力来完成辅助任务。委托强调的是行为的传递和执行,而不是对象所有权或生命周期的管理
function+bind
参考:https://blog.csdn.net/qq_38410730/article/details/103637778
https://www.cnblogs.com/linuxAndMcu/p/14576162.html#_label1
# include
std::function<函数类型>
std::function是一个可调用对象包装器,是一个类模板,可以容纳除了类成员函数指针之外的所有可调用对象,它可以用统一的方式处理函数、函数对象、函数指针,并允许保存和延迟它们的执行。
# include
std::bind(函数指针, 绑定对象);
std::bind可以看作一个通用的函数适配器,它接受一个可调用对象,生成一个新的可调用对象来适应原对象的参数列表
这样就可以实现:直接将具体观察者实例和观察者类状态更新接口函数(即之前的update)绑定。通知类管理的通知对象就从观察者实例变成了观察者的函数对象了。
也就是达到了:通知类不再依赖抽象观察者类的update接口,而是直接依赖这个绑定的函数对象。这样就可以达到:不需要抽象观察者类并且可以使用不同的接口名。
参考:https://blog.csdn.net/weixin_43272766/article/details/94166777
#include
#include
#include
#include
using namespace std;
//
typedef function<void()> Action;
// 抽象观察者 无
// 抽象通知者
class Subject
{
protected:
list<Action *> actions;
public:
string event;
virtual void attach(Action *a) = 0;
virtual void detach(Action *a) = 0;
virtual void notify() = 0;
};
// 具体通知者,秘书
class Secretary : public Subject
{
public:
void attach(Action *a) override
{
actions.push_back(a);
}
void detach(Action *a) override
{
actions.remove(a);
}
void notify() override
{
for (auto act : actions)
{
(*act)();
}
}
};
// 具体的观察者,看股票的
class StockObserver
{
private:
string name;
Subject *sub;
public:
StockObserver(string _name, Subject *_sub) : name(_name), sub(_sub)
{
}
void StockObserverUpdate()
{
cout << name << " 收到消息:" << sub->event << endl;
if (sub->event == "梁所长来了!")
{
cout << "我马上关闭股票,装做很认真工作的样子!" << endl;
}
}
};
// 具体的观察者,看NBA的
class NBAObserver
{
private:
string name;
Subject *sub;
public:
NBAObserver(string _name, Subject *_sub) : name(_name), sub(_sub)
{
}
void NBAObserverUpdate()
{
cout << name << " 收到消息:" << sub->event << endl;
if (sub->event == "梁所长来了!")
{
cout << "我马上关闭股票,装做很认真工作的样子!" << endl;
}
}
};
int main()
{
// 创建通知者
Subject *dwq = new Secretary();
// 被观察的对象
NBAObserver *xs = new NBAObserver("xiaoshuai", dwq);
Action acA = bind(&NBAObserver::NBAObserverUpdate, xs);
StockObserver *lm = new StockObserver("limin", dwq);
Action acB = bind(&StockObserver::StockObserverUpdate, lm);
// 加入观察者队列
dwq->attach(&acA);
dwq->attach(&acB);
// 事件
dwq->event = "去吃饭了!";
// 通知
dwq->notify();
cout << endl;
// 事件
dwq->event = "梁所长来了!";
// 通知
dwq->notify();
cout << endl;
return 0;
}