設計模式之委派模式

文章目錄

  • 前言
  • 正文
    • 一、生活中的例子
    • 二、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.pswp.cn/news/696297.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696297.shtml
英文地址,請注明出處:http://en.pswp.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)樸素貝葉斯需要條件獨立假設…