GOF23
種設計模式中。Delegate Pattern
)的基本做用就是負責任務的調用和分配任務,跟代理模式很像,能夠看作是一種特殊狀況下的靜態代理 的全權代理,可是代理模式注重過程,而委派模式注重結果。Spring
中應用很是多,你們經常使用的 DispatcherServlet
其實就是用到了委派模式。Boss
給 Leader
下發任務後, Leader
會根據實際狀況來分配給響應的組員,咱們將這一實際場景進行抽象化處理,用代碼來進行實現
Leader
與 Target
的共有父接口public interface IEmployee { void doWork(String commd); }
編寫普通員工類:java
public class EmployeeA implements IEmployee { @Override public void doWork(String commd) { System.out.println("EmployeeA 正在處理 "+commd +"任務"); } }
public class EmployeeB implements IEmployee { @Override public void doWork(String commd) { System.out.println("EmployeeB 正在處理 "+commd +"任務"); } }
編寫 Leader
實現:算法
public class Leader implements IEmployee { private static Map<String,IEmployee> handlerMapping = new HashMap<>(); public Leader(){ //初始化規則 handlerMapping.put("Login",new EmployeeA()); handlerMapping.put("Pay",new EmployeeB()); } @Override public void doWork(String commd) { handlerMapping.get(commd).doWork(commd); } }
在初始化 Leader 時咱們首先將對應的規則記錄,也就是委派的規則,那些任務須要派給A
, 那麼任務須要派給B
,後期的其餘需求也是在這裏進行擴展
編寫 Boss
類:設計模式
/** * @author: anonystar * @time: 2020/5/27 16:48 */ public class Boss { private Leader leader; public Boss(Leader leader){ this.leader = leader; } public void command(String cmd) { //委派分發 leader.doWork(cmd); } }
測試代碼:安全
/** * @author: anonystar * @time: 2020/5/28 9:40 */ public class SimpleDelegateTest { public static void main(String[] args) { //客戶請求(Boss)、委派者(Leader)、被被委派者(Target) // 委派者要持有被委派者的引用 // 代理模式注重的是過程, 委派模式注重的是結果 // 策略模式注重是可擴展(外部擴展),委派模式注重內部的靈活和複用 // 委派的核心:就是分發、調度、派遣 // Boss boss = new Boss(new Leader()); boss.command("Pay"); } }
前提:微信
實際問題:app
名爲上下文的原始類必須包含一個成員變量來存儲對於每種策略的引用。 上下文並不執行任務, 而是將工做委派給已鏈接的策略對象。ide
上下文不負責選擇符合任務須要的算法——客戶端會將所需策略傳遞給上下文。 實際上, 上下文並不十分了解策略, 它會經過一樣的通用接口與全部策略進行交互, 而該接口只需暴露一個方法來觸發所選策略中封裝的算法便可。函數
所以, 上下文可獨立於具體策略。 這樣你就可在不修改上下文代碼或其餘策略的狀況下添加新算法或修改已有算法了。測試
/** * 路線接口 * @author: anonystar * @url: i-code.online * @time: 2020/6/8 16:51 */ public interface Route { String ROUTE_WALK = "walk"; String ROUTE_CAR = "car"; String ROUTE_CYCLING = "cycling"; public void doRoute(); }
Route
接口/** * 駕車線路 * @author: anonystar * @url: i-code.online * @time: 2020/6/8 16:58 */ public class CarRoute implements Route { @Override public void doRoute() { System.out.println("======== 駕車線路 start ========="); } }
/** * 騎行線路 * @author: anonystar * @url: i-code.online * @time: 2020/6/8 17:01 */ public class CyclingRoute implements Route { @Override public void doRoute() { System.out.println("======== 騎行線路 start ========="); } }
/** * 步行線路 * @author: anonystar * @url: i-code.online * @time: 2020/6/8 17:02 */ public class WalkRoute implements Route { @Override public void doRoute() { System.out.println("======== 步行線路 start ========="); } }
package org.strategy.travel; /** * 構建路線 上下文 * @author: anonystar * @url: i-code.online * @time: 2020/6/9 14:45 */ public class RouteContext { // 上下文會維護指向某個策略對象的引用。上下文不知曉策略的具體類。 // 上下文必須經過策略接口來與全部策略進行交互。 private Route route; // 上下文一般會經過構造函數來接收策略對象, // 同時還提供設置器以便在運行時切換策略。 public RouteContext(Route route){ this.route = route; } public void setRoute(Route route) { this.route = route; } // 上下文會將一些工做委派給策略對象,而不是自行實現不一樣版本的算法。 public void execute(){ route.doRoute(); } }
public void travle3(){ String cmd = "walk"; RouteContext route = null; if (cmd.equals(Route.ROUTE_WALK)){ route = new RouteContext(new WalkRoute()); }else if (cmd.equals(Route.ROUTE_CAR)){ route = new RouteContext( new CarRoute()); } route.execute(); }
上面代碼咱們會發現若是有不少策略時,那麼會形成大量的if語句,這裏咱們可使用工廠模式來進行簡化,能夠看咱們以前的文章在i-code.online
package org.strategy.travel; import java.util.HashMap; import java.util.Map; /** * 獲取上下文工廠 * @author: anonystar * @url: i-code.online * @time: 2020/6/8 17:22 */ public class RouteContextFactory { private static Map<String,Route> routeMap = new HashMap<>(); private RouteContextFactory(){ } static { routeMap.put(Route.ROUTE_CAR,new CarRoute()); routeMap.put(Route.ROUTE_WALK,new WalkRoute()); routeMap.put(Route.ROUTE_CYCLING,new CyclingRoute()); } public static RouteContext getRoute(String cmd){ Route route = routeMap.get(cmd); if ( null == route){ route = routeMap.get(Route.ROUTE_CAR); } return new RouteContext(route); } }
/** * 經過工廠方法來簡化 */ public static void travle4(){ String cmd = "car"; RouteContext route = RouteContextFactory.getRoute(cmd); route.execute(); }
當你想使用對象中各類不一樣的算法變體, 並但願能在運行時切換算法時, 可以使用策略模式。this
策略模式讓你可以將對象關聯至能夠不一樣方式執行特定子任務的不一樣子對象, 從而以間接方式在運行時更改對象行爲。
當你有許多僅在執行某些行爲時略有不一樣的類似類時, 可以使用策略模式。
策略模式讓你能將不一樣行爲抽取到一個獨立類層次結構中, 並將原始類組合成同一個, 從而減小重複代碼。
若是算法在上下文的邏輯中不是特別重要, 使用該模式能將類的業務邏輯與其算法實現細節隔離開來。
策略模式讓你能將各類算法的代碼、 內部數據和依賴關係與其餘代碼隔離開來。 不一樣客戶端可經過一個簡單接口執行算法, 並能在運行時進行切換。
當類中使用了複雜條件運算符以在同一算法的不一樣變體中切換時, 可以使用該模式。
策略模式將全部繼承自一樣接口的算法抽取到獨立類中, 所以再也不須要條件語句。 原始對象並不實現全部算法的變體, 而是將執行工做委派給其中的一個獨立算法對象。
本文由AnonyStar 發佈,可轉載但需聲明原文出處。
仰慕「優雅編碼的藝術」 堅信熟能生巧,努力改變人生
歡迎關注微信公帳號 :雲棲簡碼 獲取更多優質文章
更多文章關注筆者博客 : 雲棲簡碼