0134_委托模式 (Delegate)

news/2025/9/26 7:47:17/文章来源:https://www.cnblogs.com/wanwei2018/p/19112418

委托模式 (Delegate)

意图

两个对象参与处理同一个请求,接收请求的对象将请求委托给另一个对象来处理。

委托模式的核心思想是:一个对象将某些职责交给另一个专门的对象去完成,从而实现职责的分离和代码的复用。

UML 图

delegate

优点

  1. 职责清晰分离:将具体实现逻辑与调用逻辑分离,每个类专注于自己的职责
  2. 易于扩展和维护:可以轻松添加新的委托实现,而不影响现有代码
  3. 提高代码复用性:多个委托者可以共享同一个委托对象
  4. 灵活性高:可以在运行时动态切换委托对象
  5. 符合开闭原则:对扩展开放,对修改关闭

缺点

  1. 增加系统复杂度:需要创建更多的类和接口
  2. 可能造成过度设计:对于简单场景,使用委托模式可能显得繁琐
  3. 调试难度增加:调用链变长,问题定位可能更困难
  4. 性能开销:多了一层方法调用,可能带来轻微的性能损失

代码示例:人类与机器人任务委托系统

场景描述

在一个智能工厂中,人类主管将不同类型的生产任务委托给** specialized 机器人**去执行。每个机器人专门负责特定类型的任务。

1. 任务接口 (Task Interface)

// 任务接口 - 定义所有机器人需要实现的能力
public interface Task {/*** 执行任务* @param taskDetails 任务详细信息* @return 执行结果*/String execute(String taskDetails);/*** 获取机器人类型*/String getRobotType();/*** 检查是否能够处理该任务*/boolean canHandle(String taskType);
}

2. 具体委托类 (Concrete Delegates)

// 装配机器人 - 专门负责装配任务
public class AssemblyRobot implements Task {private String name;public AssemblyRobot(String name) {this.name = name;}@Overridepublic String execute(String taskDetails) {return String.format("🔧 装配机器人[%s]正在执行装配任务: %s\n" +"   - 精确组装零部件\n" +"   - 质量检测\n" +"   - 完成产品装配", name, taskDetails);}@Overridepublic String getRobotType() {return "装配机器人";}@Overridepublic boolean canHandle(String taskType) {return taskType.contains("装配") || taskType.contains("组装") || taskType.contains("生产");}
}// 运输机器人 - 专门负责物料运输
public class TransportRobot implements Task {private String name;public TransportRobot(String name) {this.name = name;}@Overridepublic String execute(String taskDetails) {return String.format("🚚 运输机器人[%s]正在执行运输任务: %s\n" +"   - 路径规划\n" +"   - 安全运输\n" +"   - 送达目的地", name, taskDetails);}@Overridepublic String getRobotType() {return "运输机器人";}@Overridepublic boolean canHandle(String taskType) {return taskType.contains("运输") || taskType.contains("搬运") || taskType.contains("送达");}
}// 检测机器人 - 专门负责质量检测
public class InspectionRobot implements Task {private String name;public InspectionRobot(String name) {this.name = name;}@Overridepublic String execute(String taskDetails) {return String.format("🔍 检测机器人[%s]正在执行检测任务: %s\n" +"   - 外观检查\n" +"   - 功能测试\n" +"   - 质量评估", name, taskDetails);}@Overridepublic String getRobotType() {return "检测机器人";}@Overridepublic boolean canHandle(String taskType) {return taskType.contains("检测") || taskType.contains("检查") || taskType.contains("测试");}
}// 焊接机器人 - 专门负责焊接任务
public class WeldingRobot implements Task {private String name;public WeldingRobot(String name) {this.name = name;}@Overridepublic String execute(String taskDetails) {return String.format("⚡ 焊接机器人[%s]正在执行焊接任务: %s\n" +"   - 精确定位焊接点\n" +"   - 自动焊接\n" +"   - 焊缝检查", name, taskDetails);}@Overridepublic String getRobotType() {return "焊接机器人";}@Overridepublic boolean canHandle(String taskType) {return taskType.contains("焊接") || taskType.contains("连接");}
}

3. 委托者类 (Delegator)

// 人类主管 - 委托者类
public class HumanSupervisor {private String name;private List<Task> availableRobots;private Task currentDelegate;public HumanSupervisor(String name) {this.name = name;this.availableRobots = new ArrayList<>();initializeRobots();}private void initializeRobots() {availableRobots.add(new AssemblyRobot("装配大师-001"));availableRobots.add(new TransportRobot("迅捷运输-002"));availableRobots.add(new InspectionRobot("精密检测-003"));availableRobots.add(new WeldingRobot("焊接专家-004"));}/*** 委托任务给合适的机器人*/public String delegateTask(String taskType, String taskDetails) {System.out.println(String.format("\n👨‍💼 主管[%s]收到任务: %s - %s", name, taskType, taskDetails));// 寻找合适的机器人Task suitableRobot = findSuitableRobot(taskType);if (suitableRobot == null) {return String.format("❌ 错误: 没有找到能够处理'%s'任务的机器人", taskType);}this.currentDelegate = suitableRobot;System.out.println(String.format("   → 委托给: %s[%s]", suitableRobot.getRobotType(), getRobotName(suitableRobot)));// 执行委托return suitableRobot.execute(taskDetails);}/*** 动态添加新的机器人*/public void addRobot(Task robot) {availableRobots.add(robot);System.out.println(String.format("✅ 新机器人上线: %s[%s]", robot.getRobotType(), getRobotName(robot)));}/*** 显示所有可用的机器人*/public void displayAvailableRobots() {System.out.println(String.format("\n📋 主管[%s]可调度的机器人:", name));for (int i = 0; i < availableRobots.size(); i++) {Task robot = availableRobots.get(i);System.out.println(String.format("   %d. %s - %s", i + 1, robot.getRobotType(), getRobotName(robot)));}}private Task findSuitableRobot(String taskType) {return availableRobots.stream().filter(robot -> robot.canHandle(taskType)).findFirst().orElse(null);}private String getRobotName(Task robot) {// 通过反射获取机器人的name字段(简化实现)try {java.lang.reflect.Field field = robot.getClass().getDeclaredField("name");field.setAccessible(true);return (String) field.get(robot);} catch (Exception e) {return "未知";}}// Getter方法public Task getCurrentDelegate() {return currentDelegate;}public List<Task> getAvailableRobots() {return new ArrayList<>(availableRobots);}
}

4. 客户端代码

public class DelegatePatternDemo {public static void main(String[] args) {System.out.println("=== 委托模式演示 - 人类与机器人任务协作系统 ===\n");// 创建人类主管HumanSupervisor supervisor = new HumanSupervisor("张主管");// 显示可用机器人supervisor.displayAvailableRobots();// 演示任务委托System.out.println("\n" + "=".repeat(50));System.out.println("开始任务委托演示:");System.out.println("=".repeat(50));// 委托装配任务String result1 = supervisor.delegateTask("装配任务", "汽车发动机组装");System.out.println(result1);// 委托运输任务String result2 = supervisor.delegateTask("运输任务", "将原材料运送到生产线A");System.out.println(result2);// 委托检测任务String result3 = supervisor.delegateTask("质量检测", "成品手机功能测试");System.out.println(result3);// 委托焊接任务String result4 = supervisor.delegateTask("焊接任务", "钢结构框架连接");System.out.println(result4);// 演示动态添加新机器人System.out.println("\n" + "=".repeat(50));System.out.println("动态扩展演示:");System.out.println("=".repeat(50));Task newRobot = RobotFactory.createRobot("assembly", "高效装配-005");supervisor.addRobot(newRobot);supervisor.displayAvailableRobots();// 演示无法处理的任务System.out.println("\n" + "=".repeat(50));System.out.println("错误处理演示:");System.out.println("=".repeat(50));String result5 = supervisor.delegateTask("烹饪任务", "制作员工午餐");System.out.println(result5);System.out.println("\n=== 演示完成 ===");// 显示最终的委托关系System.out.println("\n最终委托状态:");System.out.println("当前委托的机器人: " + (supervisor.getCurrentDelegate() != null ? supervisor.getCurrentDelegate().getRobotType() : "无"));}
}

在Spring的应用

在Spring框架中,委托模式被广泛应用:

// Spring中的委托模式示例
@Service
public class OrderProcessingService {// 通过依赖注入委托给不同的处理器@Autowiredprivate List<OrderHandler> orderHandlers;public void processOrder(Order order) {// 委托给合适的处理器OrderHandler suitableHandler = orderHandlers.stream().filter(handler -> handler.canHandle(order.getType())).findFirst().orElseThrow(() -> new RuntimeException("No suitable handler found"));suitableHandler.handle(order);}
}// 处理器接口
public interface OrderHandler {boolean canHandle(OrderType type);void handle(Order order);
}// 具体处理器
@Service
public class OnlineOrderHandler implements OrderHandler {@Overridepublic boolean canHandle(OrderType type) {return type == OrderType.ONLINE;}@Overridepublic void handle(Order order) {// 处理在线订单}
}

总结

委托模式 vs 代理模式:

  • 委托模式:强调职责转移,委托对象真正执行任务
  • 代理模式:强调访问控制,代理对象控制对真实对象的访问

委托模式的核心价值:

  1. 专业分工:每个机器人专注于自己擅长的领域
  2. 灵活调度:人类主管可以根据任务类型动态选择最合适的执行者
  3. 易于扩展:新增机器人类型不影响现有系统
  4. 职责清晰:人类负责决策和调度,机器人负责具体执行

这种模式在现实世界的团队协作、微服务架构、任务调度系统等场景中都有广泛应用,体现了"让专业的人做专业的事"的设计哲学。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/917952.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

外贸网站建设公司平台中建国能建设集团网站

强烈建议去看看《上海交通大学生存手册》&#xff0c;内容可能有点长&#xff0c;但讲得很好&#xff0c;说出了大学教育的本质。如果几年前我能看到它&#xff0c;也许我的大学生活可能会不一样。 只是&#xff0c;没有如果。 那么我把这本手册推荐给正在上大学或者是将要上…

注册过哪些网站瑞丽航空公司官方网站

https://vjudge.net/problem/UVA-11971 有一根长度为n的木条&#xff0c;随机选k个位置把它们切成k1段小木条。求这些小木条能组成一个多边形的概率。 将木条看做一个圆&#xff0c;线上切k刀等价于圆上切k1刀 如果能组成多边形&#xff0c;每一段木条的长度都要<圆周长/2 反…

个人或企业做网络贸易的主要网站企业信用信息查询公示系统网址

ChatGLM2-6B介绍&#xff1a; 介绍 ChatGLM2-6B 是开源中英双语对话模型 ChatGLM-6B 的第二代版本&#xff0c;在保留了初代模型对话流畅、部署门槛较低等众多优秀特性的基础之上&#xff0c;ChatGLM2-6B 引入了如下新特性&#xff1a; 更强大的性能&#xff1a;基于 ChatGLM 初…

网站被黑了多久恢复wordpress 文章免审核

值转换器 valueconvert 使用ValueConverter需要实现IValueConverter接口&#xff0c;其内部有两个方法&#xff0c;Convert和ConvertBack。我们在使用Binding绑定数据的时候&#xff0c;当遇到源属性和目标控件需要的类型不一致的&#xff0c;就可以使用ValueConverter&#xf…

网站图标怎么设置建筑公司需求发布网站

SSE是server-sent events协议简称,SSE协议主要是依托于HTTP链接用来从服务端将消息、信息、事件推动给客户端的协议。 SSE简介 SSE最近突然的被很多人关注还有一个主要原因就是ChatGPT等大模型的聊天类系统就采用了SSE协议。在使用ChatGPT的时候,输入Prompt后的反馈是逐渐的…

邯郸网站设计公司排名wordpress 显示微博

大家好&#xff0c;我是『芯知识学堂』的SingleYork&#xff0c;前面给大家简单介绍了『开源项目』基于STM32的智能垃圾桶之成员简介&#xff0c;相信有很多小伙伴都已经忍不住跃跃欲试了&#xff0c;别着急&#xff0c;从这一篇开始&#xff0c;笔者将会带领大家一步一步来完成…

假如电脑的服务器关闭后做的网站还能打开吗logo在线设计生成免费

众所周知&#xff0c;验证码在我们的生活中都是非常常见的&#xff0c;很多公司都在各种折腾各种各样的验证码&#xff0c;这里简要的用一个小案例来实现验证码的功能&#xff08;ps:其实我挺讨厌验证码这个东西的&#xff09;。 建立一个javaweb工程&#xff0c;新建login.htm…

深圳微商城网站制作报价网站怎么建设以及维护

戳蓝字“CSDN云计算”关注我们哦&#xff01;极客头条&#xff1a;速递、最新、绝对有料。这里有企业新动、这里有业界要闻&#xff0c;打起十二分精神&#xff0c;紧跟fashion你可以的&#xff01;1975年4月4日&#xff0c;是历史上普通的一天。这一天&#xff0c;有两个人成立…

有关网站开发的国外书籍中国肩章

今天和大家一起探讨权限管理方面的设计心得。权限管理&#xff0c;是B端后台系统一个重要的组成部分&#xff0c;属于底层的支撑功能&#xff0c;系统内所有的功能&#xff0c;甚至字段的增减都涉及到权限的分配和管理。因此怎样配置后台的权限系统&#xff0c;以适应多变业务需…

南昌专业的电商网站开发公司新公司注册详细流程

作者| 沉默王二责编| Carol封图| CSDN│下载于视觉中国从 10 年前我开始写第一行 Java 代码至今&#xff0c;一直觉得 null 在 Java 中是一个最特殊的存在&#xff0c;它既是好朋友&#xff0c;可以把不需要的变量置为 null 从而释放内存&#xff0c;提高性能&#xff1b;它又是…

专营网站建设长安网站建设价格

目录 1.K8s什么要使用Ingress 2.在本地K8s集群安装Nginx Ingress controller 2.1.使用Kind创建本地集群 2.1.1.创建kind配置文件 2.1.2.执行创建命令 2.2.找到和当前k8s版本匹配的Ingress版本 2.2.1.查看当前的K8s版本 2.2.2.在官网中找到对应的合适版本 2.3.按照版本安…

对单位网站建设的意见wordpress主菜单导航插件

今天的分享将围绕一个大家再熟悉不过的名称展开——浏览器。 根据百科给出的解释&#xff1a;浏览器是用来检索、展示以及传递Web信息资源的应用程序。通俗的说&#xff0c;浏览器就是一种阅读工具&#xff0c;类似记事本、word、wps&#xff0c;只不过后者阅读的是文本文档&am…

怎么制作免费建网站网站数据采集怎么做

一、进程间通信原理&#xff1a; 1、通信是有成本的&#xff1a;两个或者多个进程&#xff0c;实现数据层面的交互&#xff0c;因为进程独立性的存在&#xff0c;导致进程通信的成本比较高。 2、进程间通信的方式&#xff1a; ①基本数据 ②发送命令 ③某种协同 ④通知 .....…

asp做网站计数器网站如何收费

提示&#xff1a;文章 文章目录 前言一、背景二、 2.1 2.2 总结 前言 前期疑问&#xff1a; 本文目标&#xff1a; 一、背景 最近 std::pair和std::tuple 二、用法 1.1 创建 看代码规范&#xff0c;提到&#xff1a;通过std::pair 和std::tuple &#xff0c;函数可以同…

如何给网站添加cnzzdns 部分网站打不开

MySQL是一种流行的关系型数据库管理系统&#xff0c;其中WHERE子句是用于过滤数据的重要部分。通过使用WHERE子句&#xff0c;可以根据指定的条件从表中选择特定的数据行。本文将总结MySQL WHERE子句的使用和优化方法&#xff0c;帮助读者更好地理解和应用WHERE子句&#xff0c…

北京专业制作网站公司佛山企业网站建设公司

如何彻底删除node和npm 前言&#xff1a; 最近做个项目把本地的node更新了&#xff0c;之前是v10.14.2更新至v16.14.0 &#xff0c;想着把之前的项目起来下&#xff0c;执行npm install 结果启动不了&#xff0c;一直报npm版本不匹配需要更新本地库异常… 找了几天发现是npm 和…

网站建设的销售好做吗网络哪个公司好

https://adworld.xctf.org.cn/contest/list?rwNmOdr1697354606875 目录 请求数据参数加密 cookie加密 响应数据解密 代码 请求数据参数加密 我们可以根据请求的关键字qmze1yzvhyzcyyjr获取到对应的加密地方 可以看到使用了函数_0x1dc70进行了加密 cookie加密 该步骤需…

做美工用什么素材网站门户网站维护怎么做

在我们使用电脑的时候有时候要对系统进行还原&#xff0c;那么你知道如何进行系统还原吗?不知道的小伙伴一起来操作一遍吧。 1 第一步 鼠标单击左下角的开始菜单&#xff0c;选择设置&#xff0c;进入页面 如何进行系统还原 2 第二步 单击更新和安全&#xff0c;选择左侧的恢…

长春网站快照优化公司vpswindows野外大全

介绍 希尔排序属于那种没有了解过的直接看代码一脸懵逼的&#xff0c; 所以同学们尽量不要直接看代码&#xff0c;仔细阅读本篇博客内容。 插入排序本来算是一个低效排序&#xff0c; 一次只可以挪动一个数据&#xff0c; 但是&#xff0c;它的强来了&#xff01;&#xff01…

网站开发前途塘沽网站建设优化

目录 一、部署PXE远程安装服务 1. 系统装机的三种引导方式 2. pxe概述 3. 实现过程 4. 搭建过程中服务介绍 4.1 TFTP服务 4.2 vsftp&#xff1a;安装系统镜像文件获取方式 4.3 syslinux 4.4 DHCP服务 5. 操作过程 二、实现Kickstart无人值守安装 1. 安装Kickstart图…