Skip to content
CodingDiary
返回

设计模式之行为型设计模式-委派模式

编辑页面
导读

委派模式和代理模式傻傻分不清?核心区别:代理注重过程,委派注重结果!本文用「老板-组长-工人」的场景讲解:Boss 下命令,Leader 派发任务,Worker 执行。虽然不属于 GoF 23 种设计模式,但 Spring MVC 的 DispatcherServlet 就是典型应用。

1. 模式简介

负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果;属于行为型设计模式不属于23种设计模式

2. 示例代码

/**
 * <p>
 * 工人接口
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:17
 */
public interface Worker {
    /**
     * 做事情
     *
     * @param thing 任务
     */
    void doing(String thing);
}

/**
 * <p>
 * 厨师工
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:19
 */
public class ChefWorker implements Worker {
    /**
     * 做事情
     *
     * @param thing 任务
     */
    @Override
    public void doing(String thing) {
        System.out.println("我是厨师,我接到任务,需要做美食。");
    }
}

/**
 * <p>
 * 缝纫工
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:19
 */
public class TailorWorker implements Worker {
    /**
     * 做事情
     *
     * @param thing 任务
     */
    @Override
    public void doing(String thing) {
        System.out.println("我是缝纫工,我接到任务,需要做衣服。");
    }
}
/**
 * <p>
 * 组长
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:21
 */
public class Leader implements Worker {
    private static Map<String, Worker> OFFICE = new HashMap<>();

    public Leader() {
        OFFICE.put("cooking", new ChefWorker());
        OFFICE.put("sewing", new TailorWorker());
    }

    /**
     * 做事情
     *
     * @param thing 任务
     */
    @Override
    public void doing(String thing) {
        System.out.println("我是组长,领导需要: " + thing + ",我来安排任务: " + thing);
        if (OFFICE.containsKey(thing)) {
            OFFICE.get(thing).doing(thing);
        } else {
            System.err.println("目前办公室没有对应职位的工人");
        }
    }
}
/**
 * <p>
 * 领导
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:26
 */
public class Boss {
    /**
     * 下命令
     *
     * @param thing  需要处理的事情
     * @param leader 安排给一个组长
     */
    public void command(String thing, Leader leader) {
        System.out.println("我是领导,我现在需要处理: " + thing);
        leader.doing(thing);
    }
}
/**
 * <p>
 * 委派模式,测试类
 * </p>
 *
 * @author yangkai.shen
 * @date Created in 2019/8/28 11:28
 */
public class PatternTest {
    public static void main(String[] args) {
        Boss boss = new Boss();
        boss.command("cooking", new Leader());
        System.out.println("------------------- ");
        boss.command("sewing", new Leader());
        System.out.println("------------------- ");
        boss.command("selling", new Leader());
    }
}
我是领导,我现在需要处理: cooking
我是组长,领导需要: cooking,我来安排任务: cooking
我是厨师,我接到任务,需要做美食。
-------------------
我是领导,我现在需要处理: sewing
我是组长,领导需要: sewing,我来安排任务: sewing
我是缝纫工,我接到任务,需要做衣服。
-------------------
我是领导,我现在需要处理: selling
我是组长,领导需要: selling,我来安排任务: selling
目前办公室没有对应职位的工人

3. UML 图例

4. 应用

// 在 Spring 中以 Delegate 结尾的一般都是实现了委派模式的
// 例如:BeanDefinitionParserDelegate

// Spring MVC 中的 DispatcherServlet 根据 handlerMapping 转发具体执行逻辑到 Controller

5. 优缺点

优点: 对内隐藏实现, 简化调用。

缺点: 当实际处理业务的类需要扩展时,派发命令的类也需要对应做调整,不符合开闭原则。

6. 完整代码地址

https://github.com/xkcoding/design-pattern/tree/master/src/main/java/com/xkcoding/design/pattern/behavioral/delegate


编辑页面
分享到:

上一篇
GitHub Actions 初体验
下一篇
设计模式之结构型设计模式-代理模式