设计模式之委派模式

文章目录

  • 前言
  • 正文
    • 一、生活中的例子
    • 二、Java代码实现
      • 2.1 类设计
      • 2.2 代码实现
        • 2.2.1 Employee
        • 2.2.2 ArchitectureDesignEmployer
        • 2.2.3 BackEmployer
        • 2.2.4 FrontEmployer
        • 2.2.5 Leader
        • 2.2.6 EmployeeStrongPointEnum
        • 2.2.7 Boss
      • 2.3 测试
        • 2.3.1 Client
        • 2.3.2 测试结果
    • 三、委派模式的优缺点
      • 3.1 优点
      • 3.2 缺点

前言

委派模式(Delegate Pattern)又叫委托模式,是一种面向对象的设计模式。它不属于23种设计模式之中,但同样也应用广泛。

熟悉java类加载的人都知道,java有一个双亲委派模型。就是应用了这个委派模式的思想。(但这不是我写本文的原因!)

委派模式允许对象组合实现与继承相同的代码重用。它的基本作用就是负责任务的调用和分配任务,是一种特殊的静态处理代理,可以理解为全权代理。

PS:写本文的原因在于,前几天看SpringMVC源码时遇到过。DispatcherServlet 的作用就是调节,分派请求。最终使用HandlerMapping来处理这些请求。关于这个可以参考文章:《SpringMVC原理(设计原理+启动原理+工作原理)》 的相关内容。

正文

一、生活中的例子

以生活中的例子,来研究何为委派模式。首先看一下这张图:
在这里插入图片描述
一个简单的模式,老板派发任务到经理,经理做协调,委派任务到各个不同岗位的人员。

二、Java代码实现

在第一小节中的例子,使用java代码对其进行设计并实现。

2.1 类设计

本次类的设计,使用类图展示。
在这里插入图片描述

2.2 代码实现

创建一个简单的java项目,本次使用java8。
项目结构如下:
在这里插入图片描述

2.2.1 Employee
package org.feng;/*** 员工** @author feng*/
public interface Employee {/*** 处理任务接口** @param task 任务*/void handle(String task);
}
2.2.2 ArchitectureDesignEmployer
package org.feng;import java.util.Set;/*** 架构设计师** @author feng*/
public class ArchitectureDesignEmployer implements Employee {@Overridepublic void handle(String task) {printWords();System.out.printf("现在开始处理【%s】任务!%n", task);}private void printWords() {Set<String> strongPointSet = EmployeeStrongPointEnum.getStrongPointSet(this.getClass());System.out.printf("我是架构设计师,我擅长【%s】!%n", String.join(",", strongPointSet));}
}
2.2.3 BackEmployer
package org.feng;import java.util.Set;/*** 后端开发人员** @author feng*/
public class BackEmployer implements Employee {@Overridepublic void handle(String task) {printWords();System.out.printf("现在开始处理【%s】任务!%n", task);}private void printWords() {Set<String> strongPointSet = EmployeeStrongPointEnum.getStrongPointSet(this.getClass());System.out.printf("我是后端开发人员,我擅长【%s】!%n", String.join(",", strongPointSet));}
}
2.2.4 FrontEmployer
package org.feng;import java.util.Set;/*** 前端开发人员** @author feng*/
public class FrontEmployer implements Employee {@Overridepublic void handle(String task) {printWords();System.out.printf("现在开始处理【%s】任务!%n", task);}private void printWords() {Set<String> strongPointSet = EmployeeStrongPointEnum.getStrongPointSet(this.getClass());System.out.printf("我是前端开发人员,我擅长【%s】!%n", String.join(",", strongPointSet));}
}
2.2.5 Leader
package org.feng;import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeSet;/*** 经理** @author feng*/
public class Leader implements Employee {private static final Map<String, Employee> EMPLOYEE_MAP;static {EMPLOYEE_MAP = new HashMap<>(16);try {initEmployeeMap();} catch (NoSuchMethodException | InvocationTargetException | InstantiationException |IllegalAccessException e) {throw new RuntimeException(e);}}@Overridepublic void handle(String task) {if (!EMPLOYEE_MAP.containsKey(task)) {System.out.printf("这个任务【%s】,俺做不来!%n", task);return;}// 经理委派任务到其他员工EMPLOYEE_MAP.get(task).handle(task);}private static void initEmployeeMap() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {EmployeeStrongPointEnum[] strongPoints = EmployeeStrongPointEnum.values();for (EmployeeStrongPointEnum strongPoint : strongPoints) {Class<? extends Employee> employeeClass = strongPoint.getEmployeeClass();Employee employee = employeeClass.getDeclaredConstructor().newInstance();TreeSet<String> strongPointSet = strongPoint.getStrongPoints();for (String str : strongPointSet) {EMPLOYEE_MAP.put(str, employee);}}EMPLOYEE_MAP.forEach((k, v) -> {System.out.println("EMPLOYEE_MAP: task = " + k + ", emp = " + v);});System.out.println();}
}
2.2.6 EmployeeStrongPointEnum
package org.feng;import java.util.*;/*** 员工强项枚举** @author feng*/
public enum EmployeeStrongPointEnum {ARCHITECTURE_DESIGN_EMPLOYER_STRONG_POINT(ArchitectureDesignEmployer.class, "架构设计", "架构优化"),FRONT_EMPLOYER_STRONG_POINT(FrontEmployer.class, "平面设计", "页面修改", "页面调整"),BACK_EMPLOYER_STRONG_POINT(BackEmployer.class, "数据库设计", "后端功能开发", "后端功能修改");private final Class<? extends Employee> employeeClass;private final String[] strongPoints;EmployeeStrongPointEnum(Class<? extends Employee> employeeClass, String... strongPoints) {this.employeeClass = employeeClass;this.strongPoints = strongPoints;}public Class<? extends Employee> getEmployeeClass() {return employeeClass;}public TreeSet<String> getStrongPoints() {return new TreeSet<>(Arrays.asList(strongPoints));}private static final Map<Class<? extends Employee>, TreeSet<String>> EMP_STRONG_POINT_CACHE_MAP = new HashMap<>();static {for (EmployeeStrongPointEnum strongPointEnum : EmployeeStrongPointEnum.values()) {EMP_STRONG_POINT_CACHE_MAP.put(strongPointEnum.getEmployeeClass(), strongPointEnum.getStrongPoints());}}public static Set<String> getStrongPointSet(Class<? extends Employee> employeeClass) {TreeSet<String> treeSet = EMP_STRONG_POINT_CACHE_MAP.get(employeeClass);if(treeSet == null || treeSet.isEmpty()) {return Collections.emptySet();}return treeSet;}
}
2.2.7 Boss
package org.feng;/*** 老板** @author feng*/
public class Boss {/*** 委派任务到经理** @param task   任务* @param leader 经理*/public void delegateTask(String task, Leader leader) {leader.handle(task);}
}

2.3 测试

2.3.1 Client
package org.feng;/*** 测试** @author feng*/
public class Client {public static void main(String[] args) {Boss boss = new Boss();Leader leader = new Leader();boss.delegateTask("架构设计", leader);boss.delegateTask("页面修改", leader);boss.delegateTask("测试页面功能", leader);}
}
2.3.2 测试结果
EMPLOYEE_MAP: task = 后端功能开发, emp = org.feng.BackEmployer@448139f0
EMPLOYEE_MAP: task = 页面修改, emp = org.feng.FrontEmployer@7cca494b
EMPLOYEE_MAP: task = 页面调整, emp = org.feng.FrontEmployer@7cca494b
EMPLOYEE_MAP: task = 架构设计, emp = org.feng.ArchitectureDesignEmployer@7ba4f24f
EMPLOYEE_MAP: task = 平面设计, emp = org.feng.FrontEmployer@7cca494b
EMPLOYEE_MAP: task = 后端功能修改, emp = org.feng.BackEmployer@448139f0
EMPLOYEE_MAP: task = 架构优化, emp = org.feng.ArchitectureDesignEmployer@7ba4f24f
EMPLOYEE_MAP: task = 数据库设计, emp = org.feng.BackEmployer@448139f0我是架构设计师,我擅长【架构优化,架构设计】!
现在开始处理【架构设计】任务!
我是前端开发人员,我擅长【平面设计,页面修改,页面调整】!
现在开始处理【页面修改】任务!
这个任务【测试页面功能】,俺做不来!

三、委派模式的优缺点

3.1 优点

通过任务委派能够将一个大型的任务细化,然后通过统一管理这些子任务的完成情况实现任务的跟进,能够加快任务执行的效率。

3.2 缺点

任务委派方式需要根据任务的复杂程度进行不同的改变,在任务比较复杂的情况下可能需要进行多重委派,容易造成絮乱。

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

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

相关文章

MySQL5.7.24解压版安装教程

一、MySQL5.7.24解压版安装步骤 1.在指定目录下解压压缩包。比如在D:\Program Files\mysql下解压 2.在D:\Program Files\mysql\mysql-5.7.24-winx64目录下新建data文件夹&#xff0c;如果此目录下没有my.ini也需要手动创建 3.my.ini 文件配置内容如下 [mysqld] # 设置3306端口…

Process Explorer下载安装使用教程(图文教程)超详细

「作者简介」&#xff1a;CSDN top100、阿里云博客专家、华为云享专家、网络安全领域优质创作者 「推荐专栏」&#xff1a;对网络安全感兴趣的小伙伴可以关注专栏《网络安全入门到精通》 Process Explore 是微软的一款「进程资源管理器」&#xff0c;比Windows系统自带的任务管…

20 个图像压缩工具详细分析与榜单

许多摄影师或其他专业人士将大文件大小的图像放在他们的网站上。压缩这些照片有助于缩短网站访问者的加载时间。了解各种可用的图像压缩工具可以帮助您根据操作系统和要压缩的图像数量等因素选择最好的工具。在本文中&#xff0c;我们将讨论什么是图像压缩、解释其优点并探索 2…

【C++】类与对象的项目实践 — 日期管理工具

类与对象的实践 项目背景项目需求项目实现1 日期结构设计2 构造函数2.1 全缺省构造函数2.2 拷贝构造函数2.3 析构函数 3 赋值运算符重载3.1 重载3.2 重载重载前置 和 后置 4 关系操作符重载5 工具方法5.1 计算日期差5.2 日期转换为字符串5.3 通过字符串构建对象 完整源代码Dat…

读写分离的利器——MySQL Proxy

0 引言 MySQL Proxy是一个位于客户端和MySQL服务器端之间的程序&#xff0c;通过它可以实现监听和管理客户端与MySQL服务器端之间的通信&#xff0c;最大的作用是实现数据库的读写分离&#xff0c;从而达到负载均衡的目的。 MySQL Proxy的常用用途包括负载平衡、故障分析、查…

(十)【Jmeter】线程(Threads(Users))之jp@gc - Stepping Thread Group (deprecated)

简述 操作路径如下: 作用:通过逐步增加线程数来模拟用户并发访问。配置:设置This group will start、First,wait for 、Then start、Next , add等参数。使用场景:模拟逐步增长的并发访问,观察应用程序的性能变化。优点:适用于测试应用程序在逐步增加负载下的性能表现。…

maven插件maven-assembly-plugin打包归纳文件zip/tar使用详解

文章目录 前言一、使用方式二、assembly配置文件详解1.id2.formats3.includeBaseDirectory4.fileSetdirectoryoutputDirectoryincludes、excludes 5.dependencySetsuseProjectArtifactoutputDirectoryexcludes 三、使用assembly打包jar文件总结 前言 java项目运行的文件需要ja…

MyBatis数据库查询

文章目录 什么是MyBatisMyBatis程序的创建MyBatis实现数据库查询传参查询插入实现添加操作获取自增ID删除实现修改实现#{}和${}SQL注入 like查询 resultMap和resultType多表查询 对于普遍的后端开发而言&#xff0c;其程序主要包含了后端主程序和数据库两个部分&#xff0c;用户…

Elasticsearch查询报错 Result window is too large

一现象&#xff1a; es数据分页查询前端提示系统异常&#xff0c;后端报错日志 二根本原因&#xff1a; 默认情况下&#xff0c;Elasticsearch 限制了 from size 参数的组合不能超过 10,000 条记录&#xff0c;用于防止查询大数据集时对系统资源的过度消耗 三解决办法&#…

鸿蒙开发 之 工具安装和环境搭建

DevEco Studio 面向HarmonyOS应用及元服务开发者提供的集成开发环境(IDE)&#xff0c; 助力高效开发。 ArkTS 语言 ArkTS是鸿蒙生态的应用开发语言。它在保持TypeScript&#xff08;简称TS&#xff09;基本语法风格的基础上&#xff0c;对TS的动态类型特性施加更严格的约束&…

并发List、Set、ConcurrentHashMap底层原理

并发List、Set、ConcurrentHashMap底层原理 ArrayList: List特点&#xff1a;元素有放入顺序&#xff0c;元素可重复 存储结构&#xff1a;底层采用数组来实现 public class ArrayList<E> extends AbstractList<E>implements List<E>, RandomAccess, Clon…

AUTOSAR CP--chapter7从CAN网络学习Autosar通信

从CAN网络学习Autosar通信 前言缩写词CAN通信在AUTOSAR架构中的传输上位机配置 第六章总结&#xff1a;学习了如何使用工具的自动配置功能&#xff0c;位我们生成系统描述中部分ecu的BSW模块配置&#xff0c;但是自动配置的功能虽然为我们提供了极大的便利&#xff0c;我们仍然…