设计模式中职责链 chain of responsibility案例举例

news/2024/12/29 11:00:39/

JAVA实现案例

职责链(Chain of Responsibility)模式是一种行为型模式,它将请求从发送者和接收者解耦,通过沿着一个链传递请求,使得可以多个对象都有机会处理请求。下面是一个简单的JAVA实现职责链模式的例子:

业务场景员工申请请假由经理审批,员工申请加薪则由总经理审批。

首先定义一个请求类 Request.java:

public class Request {private String requestType;private String requestDescription;public Request(String type, String description) {this.requestType = type;this.requestDescription = description;}public String getRequestType() {return requestType;}public String getRequestDescription() {return requestDescription;}
}

然后定义一个抽象处理器类 Handler.java:

public abstract class Handler {protected Handler successor;// 维持后继的责任对象public void setSuccessor(Handler successor) {this.successor = successor;}// 处理请求的方法public abstract void handleRequest(Request request);
}

接下来定义两个具体处理器类:CEOHandler.java和VPHandler.java。CEOHanlder可以批准所有请求,而VPHandler只能够处理某些特定类型的请求。

public class CEOHandler extends Handler {@Overridepublic void handleRequest(Request request) {System.out.println("CEO can approve any request.");}
}public class VPHandler extends Handler {@Overridepublic void handleRequest(Request request) {if (request.getRequestType().equals("leave")) {System.out.println("VP can approve leave requests.");} else {// 如果自己不能处理的话,就将请求转发给后继者if (successor != null) {successor.handleRequest(request);}}}
}

最后,创建一个客户端类 Client.java:

public class Client {public static void main(String[] args) {// 设置责任链CEOHandler ceoHandler = new CEOHandler();VPHandler vpHandler = new VPHandler();vpHandler.setSuccessor(ceoHandler);// 创建请求Request request1 = new Request("leave", "I want to take a leave today.");Request request2 = new Request("salary", "I want to increase my salary.");// 处理请求vpHandler.handleRequest(request1);vpHandler.handleRequest(request2);}
}

输出结果:

VP can approve leave requests.
CEO can approve any request.

这个例子中,CEOHandler担当责任链中的最后一个处理器,在它之前的处理器都没有能够处理请求时,请求会传递到CEOHandler中。而VPHandler只能够处理特定类型的请求,如果收到其他类型的请求,就会将请求传递给下一个处理器。

Python实现职责链模式

假设我们有一个餐厅系统,餐厅可以接收来自不同用户的点餐,但是每个用户都有不同的需求和特殊要求,因此我们需要一种技术来处理这些请求并将它们传递给正确的对象。在这种情况下,使用职责链模式是非常合适的。

下面是一个简单的职责链示例,用于处理来自客户端的点餐请求:

class Request:def __init__(self, meal_type, table_number, additional_request):self.meal_type = meal_typeself.table_number = table_numberself.additional_request = additional_requestclass Handler:def __init__(self, successor=None):self.successor = successordef handle_request(self, request):if self.successor is not None:return self.successor.handle_request(request)class WaiterHandler(Handler):def handle_request(self, request):if request.meal_type == "drink":print("Waiter serves drink to table", request.table_number)return Trueelse:return super().handle_request(request)class ChefHandler(Handler):def handle_request(self, request):if request.meal_type == "main_dish" and request.additional_request == "vegan":print("Chef prepares vegan dish for table", request.table_number)return Trueelse:return super().handle_request(request)class ManagerHandler(Handler):def handle_request(self, request):if request.meal_type == "complimentary_dish":print("Manager gives complimentary dish to table", request.table_number)return Trueelse:return super().handle_request(request)

在这个示例中,我们有一个处理请求的基类Handler,以及三个具体处理类WaiterHandler、ChefHandler和ManagerHandler。每个类都有一个handle_request方法来处理来自客户端的请求。如果请求无法在当前处理程序中处理,它将被传递给职责链中的下一个处理程序,直到找到一个可以处理该请求的处理程序为止。

例如,如果客户端发出一个请求要求一道素菜作为主菜,在这种情况下,只有ChefHandler处理程序才能处理该请求。因此,该请求将由ChefHandler类进行处理并返回True。如果客户端请求一杯水,则将请求失败,因为WaiterHandler处理程序将优先处理所有无需特殊处理的请求。

C ++职责链模式举例

好的,下面是一个简单的 C++ 实现职责链模式的例子:

#include <iostream>
#include <string>class Handler {
public:virtual void setNext(Handler* handler) = 0;virtual void handle(const std::string& request) = 0;
};class BaseHandler : public Handler {
public:void setNext(Handler* handler) override {this->next = handler;}void handle(const std::string& request) override {if (this->next) {this->next->handle(request);}}private:Handler* next = nullptr;
};class ConcreteHandler1 : public BaseHandler {
public:void handle(const std::string& request) override {if (request == "one") {std::cout << "Handled by ConcreteHandler1" << std::endl;} else {BaseHandler::handle(request);}}
};class ConcreteHandler2 : public BaseHandler {
public:void handle(const std::string& request) override {if (request == "two") {std::cout << "Handled by ConcreteHandler2" << std::endl;} else {BaseHandler::handle(request);}}
};class ConcreteHandler3 : public BaseHandler {
public:void handle(const std::string& request) override {if (request == "three") {std::cout << "Handled by ConcreteHandler3" << std::endl;} else {BaseHandler::handle(request);}}
};int main() {ConcreteHandler1 handler1;ConcreteHandler2 handler2;ConcreteHandler3 handler3;handler1.setNext(&handler2);handler2.setNext(&handler3);handler1.handle("one");handler1.handle("two");handler1.handle("three");handler1.handle("four");return 0;
}

运行结果:

Handled by ConcreteHandler1
Handled by ConcreteHandler2
Handled by ConcreteHandler3

在上面的例子中,Handler 类提供了处理请求的接口,并定义了设置下一个处理者的方法。BaseHandler 类实现了 Handler 接口,并提供了设置下一个处理者和调用下一个处理者的默认实现。

ConcreteHandler1、ConcreteHandler2 和 ConcreteHandler3 都继承自 BaseHandler,它们分别处理 “one”、“two” 和 “three” 请求,如果无法处理,则将请求交给下一个处理者来处理。

最后,在 main 函数中,我们可以构建出一条处理链,即 handler1 -> handler2 -> handler3。然后依次向 handler1 发送不同的请求,看看它们是否被正确地处理。

PHP案例

以下是职责链模式的PHP示例代码:


<?php// 定义处理器接口
interface Handler
{public function setNext(Handler $handler): Handler;public function handle(Request $request): ?string;
}// 请求类
class Request
{private $type;public function __construct(string $type){$this->type = $type;}public function getType(): string{return $this->type;}
}// 简单处理器实现
class SimpleHandler implements Handler
{private $nextHandler;public function setNext(Handler $handler): Handler{$this->nextHandler = $handler;return $handler;}public function handle(Request $request): ?string{if ($request->getType() === 'simple') {return 'SimpleHandler: 处理了请求类型为 simple 的请求。';}// 将请求传递给下一个处理器处理if ($this->nextHandler) {return $this->nextHandler->handle($request);}return null;}
}// 复杂处理器实现
class ComplexHandler implements Handler
{private $nextHandler;public function setNext(Handler $handler): Handler{$this->nextHandler = $handler;return $handler;}public function handle(Request $request): ?string{if ($request->getType() === 'complex') {return 'ComplexHandler: 处理了请求类型为 complex 的请求。';}// 将请求传递给下一个处理器处理if ($this->nextHandler) {return $this->nextHandler->handle($request);}return null;}
}// 客户端代码
$simpleHandler = new SimpleHandler();
$complexHandler = new ComplexHandler();$simpleHandler->setNext($complexHandler);// 处理简单请求
$request1 = new Request('simple');
$result1 = $simpleHandler->handle($request1);
echo $result1 . "\n";// 处理复杂请求
$request2 = new Request('complex');
$result2 = $simpleHandler->handle($request2);
echo $result2 . "\n";

在这个示例中,我们定义了一个处理器接口 Handler,并实现了两个不同的处理器类 SimpleHandlerComplexHandler。这两个处理器类都实现了 Handler 接口,并且可以相互串联起来形成一个处理器链。在客户端代码中,我们首先创建了一个简单处理器和一个复杂处理器,并使用 setNext 方法将它们串联起来。然后,我们分别创建了一个简单请求和一个复杂请求,并将它们传递给处理器链中的第一个处理器(即简单处理器),让它们依次经过处理器链中的所有处理器进行处理。最终,我们得到了相应的处理结果。

职责链模式的主要思想就是将一个大的请求处理过程拆分成多个小的请求处理过程,并将它们串联起来形成一个处理器链,在客户端代码中依次将请求传递给处理器链中的第一个处理器,在处理器链中依次经过所有处理器进行处理,直到得到最终的结果。


http://www.ppmy.cn/news/56399.html

相关文章

从训练数据视角:看机器学习和深度学习的大三范式

从训练数据视角&#xff1a;机器学习和深度学习 “模型”的大三范式 训练数据一般分为两个部分&#xff0c;一部分是数据本身&#xff0c;一部分是标注(Label)。训练是通过数据对应的标注&#xff0c;让模型理解数据。 1.监督学习 即训练直接输入数据和对应的标注&#xff0…

中国社会科学院大学与美国杜兰大学金融管理硕士——只要出发就会顺利抵达彼岸

新的地方会发生新的故事&#xff0c;新的相遇会碰撞出新的火花。只要出发&#xff0c;我们就会顺利抵达我们想去的远方。就像选择在社科院杜兰大学金融管理硕士项目读研的我们&#xff0c;在这里与来自全国各地的精英同学相聚&#xff0c;共享行业前沿资讯&#xff0c;聆听名师…

智能算法系列之基于粒子群优化的模拟退火算法

文章目录 前言1. 算法结合思路2. 问题场景2.1 Sphere2.2 Himmelblau2.3 Ackley2.4 函数可视化 3. 算法实现代码仓库&#xff1a;IALib[GitHub] 前言 本篇是智能算法(Python复现)专栏的第四篇文章&#xff0c;主要介绍粒子群优化算法与模拟退火算法的结合&#xff0c;以弥补各自…

C#开发的OpenRA游戏的加载地图流程

C#开发的OpenRA游戏的加载地图流程 OpenRA游戏里,地图是一个很关键的数据, 因为地图里包括了地面状态,地面上建筑物状态, 还有玩家在地图上的布局情况,以及各种活动限制的条件。 在OpenRA里,需要把地图目录:OpenRA\mods\cnc\maps 里所有的文件进行加载, 并且保存在缓…

IDEA 使用系列之 Alibaba Cloud Toolkit 一件部署

一、前文 做开发&#xff0c;免不了要往服务器部署前端后端&#xff0c;首先要用xftp把前后端所在文件夹打开&#xff0c;把jar、dist备份再上传&#xff0c;然后再打开xshell把前后端kill掉&#xff0c;然后再敲命令重新启动前后端&#xff0c;少则2、3分钟&#xff0c;多则10…

使用BP神经网络和Elman Net预测航班价格(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

ESP32-硬件IIC读取温湿度传感器SHT30

简介 esp32 使用硬件I2C读取温湿度传感器SHT30,例程基于EDP-IDF-4.4.X 的I2C Simple Example 例程修改 工程创建 打开 VSCODE ,通过 查看-- 命令面板&#xff08;快捷键CtrlShiftP&#xff09;&#xff0c;打开 ESP-IDF 的例程后&#xff0c;选择 i2c_simple 例程&#xff0…

【2023/04/21-04/28】回溯算法

学习链接&#xff1a; 回溯算法解题套路框架回溯算法秒杀所有排列-组合-子集问题一文秒杀所有岛屿题目 1.分割回文串 题目来源&#xff1a;131.分割回文串 题解&#xff1a; class Solution { public:vector<vector<int>> f;vector<vector<string>&g…