标签:employee 隔离 代理 模拟 获取 print tar 了解 交互
GOF23
种设计模式中。Delegate Pattern
)的基本作用就是负责任务的调用和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理 的全权代理,但是代理模式注重过程,而委派模式注重结果。委派模式在 Spring
中应用非常多,大家常用的 DispatcherServlet
其实就是用到了委派模式。
现实生活中也常有委 派的场景发生,例如:老板(Boss)给项目经理(Leader)下达任务,项目经理会根据 实际情况给每个员工派发工作任务,待员工把工作任务完成之后,再由项目经理汇报工 作进度和结果给老板。
上述工作中的场景是大家熟悉的,当 Boss
给 Leader
下发任务后, Leader
会根据实际情况来分配给响应的组员,我们将这一实际场景进行抽象化处理,用代码来进行实现
首先我们要明确其中的关系,客户请求(Boss)、委派者(Leader)、被委派者(Target) 在这个构建中 委派者与被委派者都服务与客户请求,只是真实的操作时让被委派者执行的,有点像静态代理
总体模型视图如下:
Leader
与 Target
的共有父接口
public interface IEmployee {
void doWork(String commd);
}
编写普通员工类:
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");
}
}
我们通过上面代码可以发现委派模式就是静态代理和策略模式一种特殊的组合
代理模式注重的是过程, 委派模式更注重的是结果
委派者要持有被委派者的引用
委派的核心:就是分发、调度、派遣
策略模式是一种行为设计模式, 它能让你定义一系列算法, 并将每种算法分别放入独立的类中, 以使算法的对象能够相互替换。
此模式让算法的变化不会影响到使用算法的用户
1、假如系统中有很多类,而他们的区别仅仅在于他们的行为不同。
2、一个系统需要动态地在几种算法中选择一种。
前提:
假设你为旅游者们设计了一款导游程序。 该程序的核心功能是提供美观的地图, 以帮助用户在任何城市中快速定位。
用户期待的程序新功能是自动路线规划: 他们希望输入地址后就能在地图上看到前往目的地的最快路线。
程序的首个版本只能规划公路路线,这满足了驾车旅行的人们的需求,但是也很明显的会忽略其他选择,所以你需要在一次次的迭代中增加新的规划线路方案,如增加步行线路、公共交通线路等等。
你以为这样就够了?这只是个开始,没多久时间你又要为骑行者规划路线。 又过了一段时间, 你又要为游览城市中的所有景点规划路线。此时相信面对不断臃肿的代码已经苦不堪言了,每次都的改动大量的代码
实际问题:
每次线路的增加都让整个开发团队非常头痛,因为每次增加新的线路规划后整个代码中的主体类都会增加一倍,慢慢的整个团都都无法继续维护这大量凌乱的代码
当在使用过程中暴露出缺陷和某些功能的微调时,那么对当前的修改都会影响到整个线路规划,同时增加了程序运行中的其他风险
越到后期团队合作将变得越低效。 尤其在后期招募了新的团队成员,他们需要大量的时间来熟悉和适应这些内容,同时在各种版本合并中挣扎。在实现新功能的过程中, 你的团队需要修改同一个巨大的类, 这样他们所编写的代码相互之间就可能会出现冲突。
名为上下文的原始类必须包含一个成员变量来存储对于每种策略的引用。 上下文并不执行任务, 而是将工作委派给已连接的策略对象。
上下文不负责选择符合任务需要的算法——客户端会将所需策略传递给上下文。 实际上, 上下文并不十分了解策略, 它会通过同样的通用接口与所有策略进行交互, 而该接口只需暴露一个方法来触发所选策略中封装的算法即可。
因此, 上下文可独立于具体策略。 这样你就可在不修改上下文代码或其他策略的情况下添加新算法或修改已有算法了。
/**
* 路线接口
* @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();
}
策略模式让你能够将对象关联至可以不同方式执行特定子任务的不同子对象, 从而以间接方式在运行时更改对象行为。
策略模式让你能将不同行为抽取到一个独立类层次结构中, 并将原始类组合成同一个, 从而减少重复代码。
策略模式让你能将各种算法的代码、 内部数据和依赖关系与其他代码隔离开来。 不同客户端可通过一个简单接口执行算法, 并能在运行时进行切换。
策略模式将所有继承自同样接口的算法抽取到独立类中, 因此不再需要条件语句。 原始对象并不实现所有算法的变体, 而是将执行工作委派给其中的一个独立算法对象。
本文由AnonyStar 发布,可转载但需声明原文出处。
仰慕「优雅编码的艺术」 坚信熟能生巧,努力改变人生
欢迎关注微信公账号 :云栖简码 获取更多优质文章
更多文章关注笔者博客 :云栖简码
标签:employee 隔离 代理 模拟 获取 print tar 了解 交互
原文地址:https://www.cnblogs.com/i-code/p/13073148.html