行为型模式:①责任链模式(Chain of Responsibility Pattern)

行为型模式:①责任链模式(Chain of Responsibility Pattern)

核心思想

将请求的处理者连成一条 “链”,请求沿着链依次传递,每个处理者仅负责处理自己职责范围内的请求,若无法处理则将请求转发给链上的下一个处理者,直至请求被处理或到达链尾。核心是 “解耦请求发送者与接收者”—— 发送者无需知道哪个处理者最终处理请求,处理者也无需知道请求的完整传递路径,仅需关注自身职责。

核心本质

链式传递 + 责任分担,通过动态构建链结构,实现请求处理的灵活扩展(如动态增减处理者、调整处理顺序)。

典型场景

审批流程(请假、报销):组长→经理→总监,按金额 / 天数分级审批;
日志级别处理(DEBUG→INFO→WARN→ERROR):不同级别日志由不同处理器处理;
异常处理链:按异常类型逐层传递,直至找到匹配的异常处理器;
请求过滤 / 拦截(如 HTTP 请求拦截器、权限校验链)。

C语言编写

场景示例

请假审批流程:
抽象处理者(Handler):定义审批接口(处理请假请求、设置下一个审批者);
具体处理者:组长(处理 1-3 天请假)、经理(处理 3-7 天请假)、总监(处理 7 天以上请假);
客户端构建审批链(组长→经理→总监),发起不同天数的请假请求,请求沿链传递直至被处理。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 最大请假人姓名长度
#define MAX_NAME 32

// 请假请求结构体(包含请求信息)
typedef struct LeaveRequest {
    char name[MAX_NAME]; // 请假人
    int days;            // 请假天数
} LeaveRequest;

// -------------------------- 1. 抽象处理者(Handler):审批接口 --------------------------
typedef struct Handler {
    // 处理请假请求(核心接口)
    void (*handle_request)(struct Handler* self, const LeaveRequest* request);
    // 设置下一个处理者(构建链)
    void (*set_next)(struct Handler* self, struct Handler* next);
    // 销毁处理者
    void (*destroy)(struct Handler* self);
    struct Handler* next; // 下一个处理者(链的核心指针)
    char title[MAX_NAME]; // 处理者职位(如组长、经理)
} Handler;

// 抽象处理者:默认设置下一个处理者
void handler_set_next(Handler* self, Handler* next) {
    self->next = next;
    printf("[%s] 下一级审批者:%s\n", self->title, next ? next->title : "无");
}

// -------------------------- 2. 具体处理者(ConcreteHandler):组长 --------------------------
typedef struct TeamLeader {
    Handler base; // 模拟继承:实现抽象接口
} TeamLeader;

// 组长:处理1-3天请假
void team_leader_handle(Handler* self, const LeaveRequest* request) {
    if (request->days >= 1 && request->days <= 3) {
        printf("\n=== 请假审批结果 ==="
               "\n请假人:%s"
               "\n请假天数:%d天"
               "\n审批人:%s"
               "\n结果:批准(1-3天属于组长审批权限)\n",
               request->name, request->days, self->title);
    } else if (self->next != NULL) {
        // 超出权限,转发给下一个处理者
        printf("\n[%s] 请假天数%d天超出权限,转发给%s审批...\n",
               self->title, request->days, self->next->title);
        self->next->handle_request(self->next, request);
    } else {
        // 无下一级处理者,审批失败
        printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
               request->name, request->days);
    }
}

// 组长:销毁
void team_leader_destroy(Handler* self) {
    if (self != NULL) {
        free(self);
        printf("[组长] 销毁审批节点\n");
    }
}

// 创建组长处理者
Handler* create_team_leader() {
    TeamLeader* leader = (TeamLeader*)malloc(sizeof(TeamLeader));
    strncpy(leader->base.title, "组长", MAX_NAME);
    leader->base.handle_request = team_leader_handle;
    leader->base.set_next = handler_set_next;
    leader->base.destroy = team_leader_destroy;
    leader->base.next = NULL;
    return (Handler*)leader;
}

// -------------------------- 3. 具体处理者(ConcreteHandler):经理 --------------------------
typedef struct Manager {
    Handler base; // 模拟继承:实现抽象接口
} Manager;

// 经理:处理3-7天请假
void manager_handle(Handler* self, const LeaveRequest* request) {
    if (request->days > 3 && request->days <= 7) {
        printf("\n=== 请假审批结果 ===\n"
               "请假人:%s\n"
               "请假天数:%d天\n"
               "审批人:%s\n"
               "结果:批准(3-7天属于经理审批权限)\n",
               request->name, request->days, self->title);
    } else if (self->next != NULL) {
        // 超出权限,转发给下一个处理者
        printf("\n[%s] 请假天数%d天超出权限,转发给%s审批...\n",
               self->title, request->days, self->next->title);
        self->next->handle_request(self->next, request);
    } else {
        printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
               request->name, request->days);
    }
}

// 经理:销毁
void manager_destroy(Handler* self) {
    if (self != NULL) {
        free(self);
        printf("[经理] 销毁审批节点\n");
    }
}

// 创建经理处理者
Handler* create_manager() {
    Manager* manager = (Manager*)malloc(sizeof(Manager));
    strncpy(manager->base.title, "经理", MAX_NAME);
    manager->base.handle_request = manager_handle;
    manager->base.set_next = handler_set_next;
    manager->base.destroy = manager_destroy;
    manager->base.next = NULL;
    return (Handler*)manager;
}

// -------------------------- 4. 具体处理者(ConcreteHandler):总监 --------------------------
typedef struct Director {
    Handler base; // 模拟继承:实现抽象接口
} Director;

// 总监:处理7天以上请假
void director_handle(Handler* self, const LeaveRequest* request) {
    if (request->days > 7) {
        printf("\n=== 请假审批结果 ===\n"
               "请假人:%s\n"
               "请假天数:%d天\n"
               "审批人:%s\n"
               "结果:批准(7天以上属于总监审批权限)\n",
               request->name, request->days, self->title);
    } else if (self->next != NULL) {
        // 理论上总监是最后一级,此处仅作兼容
        self->next->handle_request(self->next, request);
    } else {
        printf("\n=== 请假审批结果 === 请假人:%s,天数%d天,无对应审批权限,审批失败!\n",
               request->name, request->days);
    }
}

// 总监:销毁
void director_destroy(Handler* self) {
    if (self != NULL) {
        free(self);
        printf("[总监] 销毁审批节点\n");
    }
}

// 创建总监处理者
Handler* create_director() {
    Director* director = (Director*)malloc(sizeof(Director));
    strncpy(director->base.title, "总监", MAX_NAME);
    director->base.handle_request = director_handle;
    director->base.set_next = handler_set_next;
    director->base.destroy = director_destroy;
    director->base.next = NULL;
    return (Handler*)director;
}

// -------------------------- 测试代码(客户端) --------------------------
int main() {
    // 1. 创建具体处理者
    Handler* team_leader = create_team_leader();
    Handler* manager = create_manager();
    Handler* director = create_director();

    // 2. 构建责任链:组长 → 经理 → 总监
    team_leader->set_next(team_leader, manager);
    manager->set_next(manager, director);

    // 3. 发起请假请求(不同天数)
    LeaveRequest req1 = {"张三", 2};  // 组长审批
    LeaveRequest req2 = {"李四", 5};  // 经理审批
    LeaveRequest req3 = {"王五", 10}; // 总监审批
    LeaveRequest req4 = {"赵六", 0};  // 无权限

    printf("\n=== 发起请假请求1 ===");
    team_leader->handle_request(team_leader, &req1);

    printf("\n=== 发起请假请求2 ===");
    team_leader->handle_request(team_leader, &req2);

    printf("\n=== 发起请假请求3 ===");
    team_leader->handle_request(team_leader, &req3);

    printf("\n=== 发起请假请求4 ===");
    team_leader->handle_request(team_leader, &req4);

    // 4. 销毁责任链(手动销毁每个节点)
    printf("\n=== 销毁审批链 ===");
    team_leader->destroy(team_leader);
    manager->destroy(manager);
    director->destroy(director);

    return 0;
}

关键点

1.链结构核心:抽象处理者(Handler)通过 next 指针持有下一个处理者,形成链表式责任链,请求沿 next 依次传递。
2.责任划分:每个具体处理者仅处理自身职责范围内的请求(如组长处理 1-3 天),超出则转发,符合 “单一职责原则”。
3.接口统一:所有处理者通过 Handler 结构体的 handle_request 函数指针提供统一接口,客户端无需区分具体处理者类型。
4.链构建灵活:客户端通过 set_next 方法动态构建链(如调整顺序为 “组长→总监” 或新增 “副总” 节点),无需修改处理者代码。
5.解耦发送者与接收者:客户端仅需发起请求到链头(组长),无需知道最终由谁审批,处理者也无需知道请求来源。
6.内存管理:需手动销毁链上每个处理者节点,避免内存泄漏(实际项目中可封装统一销毁函数,遍历链销毁所有节点)。

C++语言实现(类 + 继承 + 多态 + 链表链)

通过 “抽象基类 + 纯虚函数” 定义处理者接口,具体处理者继承基类,通过 next 指针(智能指针)构建链,利用多态实现请求转发,代码更简洁、类型更安全。

场景示例

同 C 语言:请假审批流程(抽象基类 Handler、具体处理者 TeamLeader/Manager/Director),客户端构建链并发起请求。

#include <iostream>
#include <string>
#include <memory> // 智能指针(自动管理内存)

// 请假请求类(包含请求信息)
class LeaveRequest {
public:
    LeaveRequest(std::string name, int days) 
        : name_(std::move(name)), days_(days) {}

    std::string GetName() const { return name_; }
    int GetDays() const { return days_; }

private:
    std::string name_; // 请假人
    int days_;         // 请假天数
};

// -------------------------- 1. 抽象处理者(Handler):审批基类 --------------------------
class Handler {
public:
    virtual ~Handler() = default; // 虚析构:确保子类析构被调用

    // 纯虚函数:处理请假请求(核心接口)
    virtual void HandleRequest(const LeaveRequest& request) const = 0;

    // 设置下一个处理者(构建链)
    virtual void SetNext(std::shared_ptr<Handler> next) {
        next_ = std::move(next);
        std::cout << "[" << title_ << "] 下一级审批者:" 
                  << (next_ ? next_->title_ : "无") << std::endl;
    }

protected:
    std::shared_ptr<Handler> next_; // 下一个处理者(智能指针自动管理内存)
    std::string title_;             // 处理者职位
};

// -------------------------- 2. 具体处理者(ConcreteHandler):组长 --------------------------
class TeamLeader : public Handler {
public:
    TeamLeader() { title_ = "组长"; }

    void HandleRequest(const LeaveRequest& request) const override {
        if (request.GetDays() >= 1 && request.GetDays() <= 3) {
            std::cout << "\n=== 请假审批结果 ==="
                      << "\n请假人:" << request.GetName()
                      << "\n请假天数:" << request.GetDays() << "天"
                      << "\n审批人:" << title_
                      << "\n结果:批准(1-3天属于组长审批权限)\n";
        } else if (next_) {
            // 超出权限,转发给下一个处理者(多态调用)
            std::cout << "\n[" << title_ << "] 请假天数" << request.GetDays() 
                      << "天超出权限,转发给" << next_->title_ << "审批...\n";
            next_->HandleRequest(request);
        } else {
            std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName() 
                      << ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
        }
    }
};

// -------------------------- 3. 具体处理者(ConcreteHandler):经理 --------------------------
class Manager : public Handler {
public:
    Manager() { title_ = "经理"; }

    void HandleRequest(const LeaveRequest& request) const override {
        if (request.GetDays() > 3 && request.GetDays() <= 7) {
            std::cout << "\n=== 请假审批结果 ==="
                      << "\n请假人:" << request.GetName()
                      << "\n请假天数:" << request.GetDays() << "天"
                      << "\n审批人:" << title_
                      << "\n结果:批准(3-7天属于经理审批权限)\n";
        } else if (next_) {
            std::cout << "\n[" << title_ << "] 请假天数" << request.GetDays() 
                      << "天超出权限,转发给" << next_->title_ << "审批...\n";
            next_->HandleRequest(request);
        } else {
            std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName() 
                      << ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
        }
    }
};

// -------------------------- 4. 具体处理者(ConcreteHandler):总监 --------------------------
class Director : public Handler {
public:
    Director() { title_ = "总监"; }

    void HandleRequest(const LeaveRequest& request) const override {
        if (request.GetDays() > 7) {
            std::cout << "\n=== 请假审批结果 ==="
                      << "\n请假人:" << request.GetName()
                      << "\n请假天数:" << request.GetDays() << "天"
                      << "\n审批人:" << title_
                      << "\n结果:批准(7天以上属于总监审批权限)\n";
        } else if (next_) {
            next_->HandleRequest(request);
        } else {
            std::cout << "\n=== 请假审批结果 === 请假人:" << request.GetName() 
                      << ",天数" << request.GetDays() << "天,无对应审批权限,审批失败!\n";
        }
    }
};

// -------------------------- 测试代码(客户端) --------------------------
int main() {
    // 1. 创建具体处理者(智能指针自动管理内存)
    auto team_leader = std::make_shared<TeamLeader>();
    auto manager = std::make_shared<Manager>();
    auto director = std::make_shared<Director>();

    // 2. 构建责任链:组长 → 经理 → 总监
    team_leader->SetNext(manager);
    manager->SetNext(director);

    // 3. 发起请假请求
    LeaveRequest req1("张三", 2);  // 组长审批
    LeaveRequest req2("李四", 5);  // 经理审批
    LeaveRequest req3("王五", 10); // 总监审批
    LeaveRequest req4("赵六", 0);  // 无权限

    std::cout << "\n=== 发起请假请求1 ===";
    team_leader->HandleRequest(req1);

    std::cout << "\n=== 发起请假请求2 ===";
    team_leader->HandleRequest(req2);

    std::cout << "\n=== 发起请假请求3 ===";
    team_leader->HandleRequest(req3);

    std::cout << "\n=== 发起请假请求4 ===";
    team_leader->HandleRequest(req4);

    return 0; // 智能指针自动销毁所有处理者,无需手动释放
}

实现关键要点

1.抽象基类定义接口:Handler 基类用纯虚函数 HandleRequest 定义统一审批接口,SetNext 方法用于构建链,确保所有处理者接口一致。
2.多态转发核心:请求处理时,若当前处理者无法处理,通过 next_ 智能指针调用下一个处理者的 HandleRequest,多态确保调用正确的具体实现。
3.智能指针管理内存:next_ 用 std::shared_ptr 管理下一个处理者,自动销毁链上所有节点,避免内存泄漏;虚析构函数确保子类析构被正确调用。
4.链构建灵活:客户端可动态调整链结构(如新增 “副总” 节点、调整顺序为 “组长→总监”),无需修改处理者代码,符合 “开闭原则”。
5.责任划分清晰:每个具体处理者仅关注自身职责范围,无需关心链的整体结构,职责单一,代码可维护性强。
6.解耦彻底:客户端仅需发起请求到链头(组长),无需知道最终审批人;处理者仅需知道下一个处理者,无需知道请求来源和后续节点,耦合度极低。

责任链模式核心总结(C vs C++)

在这里插入图片描述

设计原则

单一职责原则:每个处理者仅处理自身职责内的请求;
开闭原则:新增处理者或调整链结构无需修改现有代码;
依赖倒置原则:客户端依赖抽象处理者,不依赖具体处理者。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值