责任链模式
- BaseHandler:抽象基类,用于作为处理请求的接口。如果特定等级的请求该类无法处理,则传递给下一个handler,一般这类情况class内部都是纯虚函数。
- ConcreteHandler(TechnicalSupportHandler, BillingSupportHandler, and GeneralSupportHandler):处理请求,或将请求传递给handler链中的下一个,这样可以通过设计整个逻辑链避免混乱
- Client(RequestorClient):发起请求,一般是放在主程序中传入
示例:
#include <iostream>
using namespace std;
//抽象处理者
class Handler
{
public:
Handler() { m_pNextHandler = NULL; }
virtual ~Handler() {}
//设置下一个处理者
void SetNextHandler(Handler *successor) { m_pNextHandler = successor; }
//处理请求
virtual void HandleRequest(int days) = 0;
protected:
Handler *m_pNextHandler; // 后继者
};
//具体处理者、主管
class Director :public Handler
{
public:
//处理请求
virtual void HandleRequest(int days)
{
if (days <= 1)
{
cout << "我是主管,有权批准一天假,同意了!" << endl;
}
else
{
m_pNextHandler->HandleRequest(days);
}
}
};
//具体处理者、经理
class Manager :public Handler
{
public:
//处理请求
virtual void HandleRequest(int days)
{
if (days <= 3)
{
cout << "我是经理,有权批准三以下的假,同意了!" << endl;
}
else
{
m_pNextHandler->HandleRequest(days);
}
}
};
//具体处理者、老板
class Boss :public Handler
{
public:
//处理请求
virtual void HandleRequest(int days)
{
if (days <= 7)
{
cout << "我是老板,最多让你请7天假,同意了!" << endl;
}
else
{
cout << "你请的假事假太长了,不同意!" << endl;
}
}
};
//场景
int main()
{
Handler *director = new Director;
Handler *manager = new Manager;
Handler *boss = new Boss;
//设置责任链
director->SetNextHandler(manager);
manager->SetNextHandler(boss);
director->HandleRequest(1);
director->HandleRequest(2);
director->HandleRequest(5);
director->HandleRequest(8);
getchar();
return 0;
}
输出:
我是主管,有权批准一天假,同意了!
我是经理,有权批准三以下的假,同意了
我是老板,最多让你请7天假,同意了!
你请的假事假太长了,不同意!
多线程方式
示例:
// mutex1.cpp 通过互斥体lock与unlock保护共享全局变量
#include <chrono>
#include <mutex>
#include <thread>
#include <iostream>
std::chrono::milliseconds interval(100);
std::mutex g_mutex;
int job_shared = 0; //两个线程都能修改'job_shared',mutex将保护此变量
int job_exclusive = 0; //只有一个线程能修改'job_exclusive',不需要保护
//此线程只能修改 'job_shared'
void job_1()
{
g_mutex.lock();
std::this_thread::sleep_for(5 * interval); //令‘job_1’持锁等待
++job_shared;
std::cout << "job_1 shared (" << job_shared << ")\n";
g_mutex.unlock();
}
// 此线程能修改'job_shared'和'job_exclusive'
void job_2()
{
while (true) { //无限循环,直到获得锁并修改'job_shared'
if (g_mutex.try_lock()) { //尝试获得锁成功则修改'job_shared'
++job_shared;
std::cout << "job_2 shared (" << job_shared << ")\n";
g_mutex.unlock();
return;
}
else { //尝试获得锁失败,接着修改'job_exclusive'
++job_exclusive;
std::cout << "job_2 exclusive (" << job_exclusive << ")\n";
std::this_thread::sleep_for(interval);
}
}
}
int main()
{
std::thread thread_1(job_1);
std::thread thread_2(job_2);
thread_1.join();
thread_2.join();
getchar();
return 0;
}
输出:
job_2 exclusive (1)
job_2 exclusive (2)
job_2 exclusive (3)
job_2 exclusive (4)
job_2 exclusive (5)
job_1 shared (1)
job_2 shared (2)
参考:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了