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 发布,可转载但需声明原文出处。
仰慕「优雅编码的艺术」 坚信熟能生巧,努力改变人生
欢迎关注微信公帐号 :云栖简码 获取更多优质文章
更多文章关注笔者博客 : 云栖简码