设计模式之委派模式

文章目录

  • 前言
  • 正文
    • 一、生活中的例子
    • 二、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.mzph.cn/news/696297.shtml

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

相关文章

Docker Desktop 4.27.1 Windows 10 安装 教程

Docker Desktop 4.27.1 Windows 10 安装 版本要求windows 版本要求wsl 版本要求docker desktop 版本 安装首先确保系统版本符合要求前提下安装wsl安装 Dockers Desktop安装说明 安装问题docker Desktop 无法正常启动&#xff0c;提示wsl 相关信息wsl --install 执行输出帮助日志…

Python 程序中查看 Python version

Python 程序中查看 Python version 1. Code2. OutputReferences 1. Code #!/usr/bin/env python3 # -*- coding:utf-8 -*-import platform import sysprint("\nplatform.python_version():") print(platform.python_version())print("\nsys.version:") pr…

springboot大学生体质测试管理系统源码和论文

大学生体质测试管理系统提供给用户一个简单方便体质测试管理信息&#xff0c;通过留言区互动更方便。本系统采用了B/S体系的结构&#xff0c;使用了java技术以及MYSQL作为后台数据库进行开发。系统主要分为系统管理员、教师和用户三个部分&#xff0c;系统管理员主要功能包括首…

图像分类入门:使用Python和Keras实现卷积神经网络

文章标题&#xff1a;图像分类入门&#xff1a;使用Python和Keras实现卷积神经网络 简介 图像分类是计算机视觉领域的一个重要任务&#xff0c;它涉及将图像分成不同的类别或标签。卷积神经网络&#xff08;CNN&#xff09;是图像分类任务中的一种常用模型&#xff0c;它能够…

rust实战系列十四:复合数据类型

复合数据类型可以在其他类型的基础上形成更复杂的组合关系。 本章介绍tuple、struct、enum等几种复合数据类型。数组留到第6章介绍。 2.3.1 tuple tuple指的是“元组”类型&#xff0c;它通过圆括号包含一组表达式构成。tuple内的元素没 有名字。tuple是把几个类型组合到一起的…

第三十九天| 62.不同路径、63. 不同路径 II

Leetcode 62.不同路径 题目链接&#xff1a;62 不同路径 题干&#xff1a;一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “…

c#之列表

// List<int> scoreList new List<int>();//创建空列表var scoreListnew List<int>();//匿名方式创建scoreList.Add(912);//插入数据scoreList.Add(45);scoreList.Add(415);scoreList.Add(452);scoreList.Add(4451);scoreList.Add(245);scoreList.Add(445);…

十六、多边形填充和绘制

项目功能实现&#xff1a;对多边形进行轮廓绘制和填充 按照之前的博文结构来&#xff0c;这里就不在赘述了 一、头文件 mult-drawing.h #pragma once#include<opencv2/opencv.hpp>using namespace cv;class Mult_Drawing { public:void mult_drawing(); };#pragma onc…

vue如何动态加载显示本地图片资源

在实际开发中&#xff0c;根据某一个变量动态展示图片的情况有很多。实现方法分打包构建工具的差异而不同。 1、webpack的项目 require引入图片资源 2、vite的项目 new URL(url,base).href 疑问解答&#xff1a;为什么vite项目不可以用require&#xff1f; 原因在于&#xf…

Elastic Stack--01--简介、安装

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 1. Elastic Stack 简介为什么要学习ESDB-Engines搜索引擎类数据库排名常年霸榜![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/051342a83f574c8c910cda…

微信小程序独立分包与分包预下载

官网链接 独立分包配置方法 独立分包使用限制 独立分包中不能依赖主包和其他分包中的内容&#xff0c;包括 js 文件、模板、wxss、自定义组件等&#xff1b;App 只能在主包内定义&#xff0c;独立分包中不能定义 App&#xff0c;会造成无法预期的行为独立分包中暂时不支持使用…

cocos creator3.x项目打包成aar 加入到已有的Android工程

Cocos crearor版本&#xff1a; 3.4.2 Android Studio Flamingo | 2022.2.1 Patch 2 1、配置构建安卓项目 2、 运行编译无报错 出现问题可尝试修改Gradle版本 修改jdk版本 3、对libservice打包成aar 打包完后 再build/outputs找到aar 如果看不到Tasks模块&#xff0c;在Fil…

sqlserver触发器

在SQL Server中&#xff0c;触发器是一种特殊的数据库对象&#xff0c;它们会在表上执行特定的操作时自动触发。触发器可以用于在表上插入、更新或删除数据时执行自定义的逻辑。触发器通常用于实施数据完整性约束、审计和日志记录等操作。 触发器有三种主要类型&#xff1a; 插…

人机交互新研究:MIT开发了结合脑电和眼电的新式眼镜,与机器狗交互

还记得之前的AI读心术吗&#xff1f;最近&#xff0c;「心想事成」的能力再次进化&#xff0c; ——人类可以通过自己的想法直接控制机器人了&#xff01; 来自麻省理工的研究人员发表了Ddog项目&#xff0c;通过自己开发的脑机接口&#xff08;BCI&#xff09;设备&#xff…

面试答疑03

1、登录鉴权怎么做的&#xff1f;为什么采用jwt的方式&#xff1f;有什么好处&#xff1f; Java登录鉴权常见的实现方式包括**CookieSession、HTTP Basic Authentication、ServletJDBC**等。 在Java的Web应用中&#xff0c;登录鉴权是确认用户身份的关键环节。一个常用的传统…

【Linux内核模块加新功能 DAY6-8】

一、向内核添加新功能 1.1 静态加载法&#xff1a; 即新功能源码与内核其它代码一起编译进uImage文件内 新功能源码与Linux内核源码在同一目录结构下在linux-3.14/driver/char/目录下编写myhello.c&#xff0c;文件内容如下&#xff1a;#include <linux/module.h> #inc…

Vue项目启动过程全记录(node.js运行环境搭建)

一、安装node.js并配置环境变量 1、安装node.js 从Node.js官网下载安装包并安装。然后在安装后的目录&#xff08;如果是下载的压缩文件&#xff0c;则是解压缩的目录&#xff09;下新建node_global和node_cache这两个文件夹。 node_global&#xff1a;npm全局安装位置 node_…

Golang 中 NATS JetStream 的高级特性有哪些?

NATS JetStream 是 NATS 消息系统的一个高级功能模块&#xff0c;提供了许多高级特性&#xff0c;使得它在处理消息时更加灵活、可靠和高效。以下是 NATS JetStream 的一些高级特性&#xff1a; 持久化消息存储&#xff1a;NATS JetStream 使用持久化存储引擎&#xff0c;可以确…

代码随想录三刷day06

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、力扣203. 移除链表元素二、力扣707. 设计链表三、力扣 前言 递归法相对抽象一些&#xff0c;但是其实和双指针法是一样的逻辑&#xff0c;同样是当cur为空的…

机器学习面试:逻辑回归与朴素贝叶斯区别

逻辑回归与朴素贝叶斯区别有以下几个方面: (1)逻辑回归是判别模型&#xff0c;朴素贝叶斯是生成模型&#xff0c;所以生成和判别的所有区别它们都有。 (2)朴素贝叶斯属于贝叶斯&#xff0c;逻辑回归是最大似然&#xff0c;两种概率哲学间的区别。 (3)朴素贝叶斯需要条件独立假设…