一、责任链模式概述
责任链模式是一种行为型设计模式,其核心思想是为请求创建一个处理者对象的链。当有请求发生时,请求会沿着这条链传递,直到链中的某一个处理者对象能够处理该请求为止。这种模式的优势在于将请求的发送者和接收者解耦,使得多个处理者可以灵活地组合成不同的责任链,并且可以动态地增加或移除处理者,改变请求的处理流程。
在日常生活中,家具生产流程就是责任链模式的典型应用场景。一件家具(如实木椅子)的生产需要经过多个环节:原材料检验、木材切割、表面打磨、部件组装、质量检测等。每个环节都有明确的职责,只有前一个环节处理完成且合格后,才会将半成品传递给下一个环节;如果某个环节发现问题,会直接反馈而不再向下传递。我们可以将每个生产环节封装为一个处理者,构成一条家具生产的责任链。
二、家具生产场景下的责任链模式设计
2.1 核心角色定义
-
抽象处理者(Handler):定义家具生产环节的统一接口,包含一个指向后续处理者的指针和处理请求的纯虚函数。对应家具生产中的"生产工序"抽象。
-
具体处理者(ConcreteHandler):实现抽象处理者的接口,完成本环节的具体处理逻辑。若处理合格则将请求传递给下一个处理者,若不合格则终止传递并反馈。对应家具生产中的"原材料检验员""切割工""打磨工"等具体岗位。
-
请求对象(Request):封装家具生产过程中的相关信息,如原材料类型、尺寸要求、半成品状态等。对应家具生产中的"生产任务单+半成品"。
2.2 场景设计思路
以实木餐桌生产为例,设计一条包含4个核心环节的责任链:
-
原材料检验:检查实木板材的材质、含水率、有无裂纹等,合格则进入切割环节。
-
木材切割:根据餐桌尺寸要求,将合格板材切割成桌面、桌腿等部件,合格则进入打磨环节。
-
表面打磨:对切割后的部件进行精细打磨,去除毛刺、棱角,合格则进入组装环节。
-
部件组装:将打磨后的部件组装成完整餐桌,合格则完成生产,不合格则返回返工。
每个环节作为具体处理者,持有下一个环节的引用,形成"原材料检验→木材切割→表面打磨→部件组装"的责任链。生产请求从第一个环节发起,依次传递直至完成或被终止。
三、C++代码实现
3.1 头文件定义(FurnitureProductionChain.h)
cpp
#include <iostream>
#include <string>
using namespace std;
// 请求对象:封装家具生产相关信息
class FurnitureRequest {
private:
string material; // 原材料类型(如"实木板材")
double size; // 尺寸要求(单位:米)
string semiProduct; // 半成品状态(如"未切割板材""切割后部件")
bool isQualified; // 前一环节是否合格
public:
FurnitureRequest(string mat, double sz)
: material(mat), size(sz), semiProduct("原始原材料"), isQualified(true) {}
// 获取和设置半成品状态
string getSemiProduct() const { return semiProduct; }
void setSemiProduct(string state) { semiProduct = state; }
// 获取和设置合格状态
bool isQualified() const { return isQualified; }
void setQualified(bool qualified) { isQualified = qualified; }
// 获取原材料信息
string getMaterial() const { return material; }
// 获取尺寸信息
double getSize() const { return size; }
};
// 抽象处理者:生产工序
class ProductionProcess {
protected:
ProductionProcess* nextProcess; // 下一个工序
public:
ProductionProcess() : nextProcess(nullptr) {}
virtual ~ProductionProcess() { delete nextProcess; } // 递归释放链
// 设置下一个工序
void setNextProcess(ProductionProcess* process) {
nextProcess = process;
}
// 处理请求(核心方法)
virtual void handleRequest(FurnitureRequest& request) = 0;
};
// 具体处理者1:原材料检验工序
class MaterialInspection : public ProductionProcess {
public:
void handleRequest(FurnitureRequest& request) override {
cout << "=== 原材料检验环节 ===" << endl;
cout << "检测原材料:" << request.getMaterial() << endl;
// 模拟检验逻辑:实木板材且含水率合格(简化判断)
if (request.getMaterial() == "实木板材" && request.getSize() > 0) {
cout << "原材料检验合格,进入下一道工序" << endl;
request.setSemiProduct("合格实木板材");
// 传递请求给下一个工序
if (nextProcess != nullptr) {
nextProcess->handleRequest(request);
}
} else {
cout << "原材料检验不合格,终止生产" << endl;
request.setQualified(false);
}
cout << "------------------------" << endl;
}
};
// 具体处理者2:木材切割工序
class WoodCutting : public ProductionProcess {
public:
void handleRequest(FurnitureRequest& request) override {
if (!request.isQualified()) {
return; // 前一环节不合格,直接返回
}
cout << "=== 木材切割环节 ===" << endl;
cout << "处理半成品:" << request.getSemiProduct() << endl;
cout << "按照尺寸 " << request.getSize() << "m 进行切割" << endl;
// 模拟切割逻辑:尺寸在合理范围内则合格
if (request.getSize() > 0.5 && request.getSize() < 2.0) {
cout << "木材切割合格,得到桌面和桌腿部件" << endl;
request.setSemiProduct("切割完成的餐桌部件");
// 传递请求给下一个工序
if (nextProcess != nullptr) {
nextProcess->handleRequest(request);
}
} else {
cout << "切割尺寸不合理,终止生产" << endl;
request.setQualified(false);
}
cout << "------------------------" << endl;
}
};
// 具体处理者3:表面打磨工序
class SurfacePolishing : public ProductionProcess {
public:
void handleRequest(FurnitureRequest& request) override {
if (!request.isQualified()) {
return; // 前一环节不合格,直接返回
}
cout << "=== 表面打磨环节 ===" << endl;
cout << "处理半成品:" << request.getSemiProduct() << endl;
// 模拟打磨逻辑:切割后的部件均可打磨(简化判断)
if (request.getSemiProduct() == "切割完成的餐桌部件") {
cout << "表面打磨完成,去除毛刺和棱角" << endl;
request.setSemiProduct("打磨合格的餐桌部件");
// 传递请求给下一个工序
if (nextProcess != nullptr) {
nextProcess->handleRequest(request);
}
} else {
cout << "半成品状态异常,打磨失败,终止生产" << endl;
request.setQualified(false);
}
cout << "------------------------" << endl;
}
};
// 具体处理者4:部件组装工序
class ComponentAssembly : public ProductionProcess {
public:
void handleRequest(FurnitureRequest& request) override {
if (!request.isQualified()) {
return; // 前一环节不合格,直接返回
}
cout << "=== 部件组装环节 ===" << endl;
cout << "处理半成品:" << request.getSemiProduct() << endl;
// 模拟组装逻辑:打磨后的部件均可组装(简化判断)
if (request.getSemiProduct() == "打磨合格的餐桌部件") {
cout << "部件组装完成,成功生产出实木餐桌!" << endl;
request.setSemiProduct("成品实木餐桌");
} else {
cout << "半成品状态异常,组装失败,终止生产" << endl;
request.setQualified(false);
}
cout << "------------------------" << endl;
}
};
3.2 主函数测试(main.cpp)
cpp
#include "FurnitureProductionChain.h"
int main() {
// 1. 创建各个处理者(生产环节)
ProductionProcess* inspection = new MaterialInspection();
ProductionProcess* cutting = new WoodCutting();
ProductionProcess* polishing = new SurfacePolishing();
ProductionProcess* assembly = new ComponentAssembly();
// 2. 构建责任链:原材料检验 → 木材切割 → 表面打磨 → 部件组装
inspection->setNextProcess(cutting);
cutting->setNextProcess(polishing);
polishing->setNextProcess(assembly);
// 3. 创建请求:生产一张1.2米的实木餐桌
FurnitureRequest tableRequest("实木板材", 1.2);
// 4. 发起请求(从第一个环节开始)
cout << "=== 开始生产实木餐桌 ===" << endl;
inspection->handleRequest(tableRequest);
// 5. 输出生产结果
cout << "=== 生产结果 ===" << endl;
if (tableRequest.isQualified()) {
cout << "生产成功!最终产品:" << tableRequest.getSemiProduct() << endl;
} else {
cout << "生产失败!" << endl;
}
// 6. 释放资源(抽象处理者析构函数会递归释放链)
delete inspection;
return 0;
}
四、代码解释
-
请求对象(FurnitureRequest):封装了生产所需的原材料、尺寸、半成品状态等信息,作为责任链中传递的数据载体,各处理者通过修改其状态来实现"请求处理"的效果。
-
抽象处理者(ProductionProcess) :定义了责任链的核心接口,包含设置下一个处理者的
setNextProcess方法和处理请求的纯虚函数handleRequest,确保所有具体处理者遵循统一的行为规范。 -
具体处理者 :每个生产环节对应一个具体处理者,实现
handleRequest方法完成本环节的业务逻辑。若处理合格,则通过nextProcess将请求传递给下一个环节;若不合格,则终止传递并标记状态。 -
客户端(main函数):负责创建各个具体处理者,并按照生产流程构建责任链,最后发起生产请求。客户端无需关心请求的具体处理过程,只需触发链的起始节点即可。
五、责任链模式在家具生产中的优势
-
灵活调整生产流程 :若需要增加"喷漆"环节,只需创建新的具体处理者并插入责任链;若需要调整环节顺序,只需修改
setNextProcess的调用顺序,无需修改原有代码,符合"开闭原则"。 -
故障快速定位:若生产失败,从输出日志可直接定位到哪个环节出现问题(如原材料不合格、切割尺寸异常等),便于排查故障。
责任链模式通过构建处理者对象链,实现了请求的动态传递与处理,非常适合像家具生产这样具有明确流程顺序、各环节职责清晰的场景。在C++实现中,通过抽象类定义接口、具体类实现业务逻辑、客户端构建链的方式,既保证了代码的规范性,又具备良好的灵活性和可扩展性。实际开发中,还可结合工厂模式创建处理者对象,进一步降低客户端与具体处理者的耦合度。