C++设计模式之责任链模式:以家具生产为例

一、责任链模式概述

责任链模式是一种行为型设计模式,其核心思想是为请求创建一个处理者对象的链。当有请求发生时,请求会沿着这条链传递,直到链中的某一个处理者对象能够处理该请求为止。这种模式的优势在于将请求的发送者和接收者解耦,使得多个处理者可以灵活地组合成不同的责任链,并且可以动态地增加或移除处理者,改变请求的处理流程。

在日常生活中,家具生产流程就是责任链模式的典型应用场景。一件家具(如实木椅子)的生产需要经过多个环节:原材料检验、木材切割、表面打磨、部件组装、质量检测等。每个环节都有明确的职责,只有前一个环节处理完成且合格后,才会将半成品传递给下一个环节;如果某个环节发现问题,会直接反馈而不再向下传递。我们可以将每个生产环节封装为一个处理者,构成一条家具生产的责任链。

二、家具生产场景下的责任链模式设计

2.1 核心角色定义

  • 抽象处理者(Handler):定义家具生产环节的统一接口,包含一个指向后续处理者的指针和处理请求的纯虚函数。对应家具生产中的"生产工序"抽象。

  • 具体处理者(ConcreteHandler):实现抽象处理者的接口,完成本环节的具体处理逻辑。若处理合格则将请求传递给下一个处理者,若不合格则终止传递并反馈。对应家具生产中的"原材料检验员""切割工""打磨工"等具体岗位。

  • 请求对象(Request):封装家具生产过程中的相关信息,如原材料类型、尺寸要求、半成品状态等。对应家具生产中的"生产任务单+半成品"。

2.2 场景设计思路

以实木餐桌生产为例,设计一条包含4个核心环节的责任链:

  1. 原材料检验:检查实木板材的材质、含水率、有无裂纹等,合格则进入切割环节。

  2. 木材切割:根据餐桌尺寸要求,将合格板材切割成桌面、桌腿等部件,合格则进入打磨环节。

  3. 表面打磨:对切割后的部件进行精细打磨,去除毛刺、棱角,合格则进入组装环节。

  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;
}

四、代码解释

  1. 请求对象(FurnitureRequest):封装了生产所需的原材料、尺寸、半成品状态等信息,作为责任链中传递的数据载体,各处理者通过修改其状态来实现"请求处理"的效果。

  2. 抽象处理者(ProductionProcess) :定义了责任链的核心接口,包含设置下一个处理者的setNextProcess方法和处理请求的纯虚函数handleRequest,确保所有具体处理者遵循统一的行为规范。

  3. 具体处理者 :每个生产环节对应一个具体处理者,实现handleRequest方法完成本环节的业务逻辑。若处理合格,则通过nextProcess将请求传递给下一个环节;若不合格,则终止传递并标记状态。

  4. 客户端(main函数):负责创建各个具体处理者,并按照生产流程构建责任链,最后发起生产请求。客户端无需关心请求的具体处理过程,只需触发链的起始节点即可。

五、责任链模式在家具生产中的优势

  1. 灵活调整生产流程 :若需要增加"喷漆"环节,只需创建新的具体处理者并插入责任链;若需要调整环节顺序,只需修改setNextProcess的调用顺序,无需修改原有代码,符合"开闭原则"。

  2. 故障快速定位:若生产失败,从输出日志可直接定位到哪个环节出现问题(如原材料不合格、切割尺寸异常等),便于排查故障。

责任链模式通过构建处理者对象链,实现了请求的动态传递与处理,非常适合像家具生产这样具有明确流程顺序、各环节职责清晰的场景。在C++实现中,通过抽象类定义接口、具体类实现业务逻辑、客户端构建链的方式,既保证了代码的规范性,又具备良好的灵活性和可扩展性。实际开发中,还可结合工厂模式创建处理者对象,进一步降低客户端与具体处理者的耦合度。

相关推荐
化作繁星2 小时前
前端设计模式详解
前端·设计模式
lynnlovemin2 小时前
从暴力到高效:C++ 算法优化实战 —— 排序与双指针篇
java·c++·算法
慕容青峰2 小时前
牛客小白月赛 103 C 题题解
c++·算法·sublime text
小龙报2 小时前
【算法通关指南:算法基础篇(四)】二维差分专题:1.【模板】差分 2.地毯
c语言·数据结构·c++·深度学习·神经网络·算法·自然语言处理
Cinema KI3 小时前
一文掌握 C++ 多态:原理、用法、坑点
c++
郝学胜-神的一滴3 小时前
Linux进程管理:借助信号回收进程
linux·服务器·开发语言·c++·程序人生
lenkco3 小时前
修改QtConcurrent::run支持任意参数
开发语言·c++·qt
CHANG_THE_WORLD3 小时前
编写 CMakeLists查找库的findxxx.cmake文件
c++
赵得C3 小时前
软件设计师前沿考点精讲:新兴技术与性能优化实战
java·开发语言·分布式·算法·设计模式·性能优化