设计模式 --- 委派模式

155 阅读2分钟

1. 委派模式作用


委派模式主要是用来做分配和调度的

2. 委派模式场景演绎


公司的老板给项目经理下达命令,要求一个月内为xxx公司开发官网,项目经理收到命令,为公司员工分配任务,公司员工接到任务后开始干活。这就是委派模式,老板委派项目经理干活,项目经理委派员工干活,老板不干活,下面用代码来实现上面的场景

2.1 创建员工接口

/**
 * 公司员工接口
 */
public interface Employee {
    void doSomething(String task);
}

2.2 创建两个员工

/**
 * 员工A
 */
public class EmployeeA implements Employee{
    @Override
    public void doSomething(String task) {
        System.out.println("EmployeeA 接到" + task + "任务,开始干活");
    }
}
/**
 * 员工B
 */
public class EmployeeB implements Employee{
    @Override
    public void doSomething(String task) {
        System.out.println("EmployeeB 接到"+ task +"任务,开始干活");
    }
}

2.3 创建项目经理

/**
 * 项目经理,它也是公司的员工,因此也实现员工接口
 */
public class ProjectManager implements Employee{

    private static final Map<String, Employee> employeeMap  = new HashMap<>();

    static {
        employeeMap.put("前端", new EmployeeA());
        employeeMap.put("后端", new EmployeeA());
    }

    @Override
    public void doSomething(String command) {
        System.out.println("项目经理收到"+ command + "的命令,为员工分配任务");
        employeeMap.get("前端").doSomething("前端");
        employeeMap.get("后端").doSomething("后端");
    }
}

2.4 创建老板

/**
 * 老板
 */
public class Boss {
    public void command(String command, Employee employee){
        employee.doSomething(command);
    }
}

2.5 主函数测试

/**
 * 老板给项目经理下达命令,要求为xxx公司开发一个网站
 */
public class DelegateMain {
    public static void main(String[] args) {
        Boss boss = new Boss();
        boss.command("为xxx公司开发一个网站", new ProjectManager());
    }
}

查看控制台打印
image.png


3. Spring 中委派模式的应用


spring 中有很多地方都用到了委派模式,比如 DispatcherServlet 根据前端请求的 url 分配处理的 Controller,下面用代码来还原一下

3.1 新建两个 Controller

@Controller
public class UserController {

    @RequestMapping("/getUserById")
    public String getById(String id){
        return "xxx";
    }
}
@Controller
public class OrderController {

    @RequestMapping("/getOrderById")
    public String getById(String id){
        return "xxx";
    }
}

3.2 新建 DispatcherServlet

/**
 * 相当于项目经理,给请求分配Controller
 */
public class DispatcherServlet extends HttpServlet {

    private void doDispatcher(HttpServletRequest request, HttpServletResponse response) throws IOException {
        String uri = request.getRequestURI();
        String id = request.getParameter("id");

        if ("getUserById".equals(uri)){
            new UserController().getById(id);
        }else if("getOrderById".equals(uri)){
            new OrderController().getById(id);
        }else{
            response.getWriter().write("404 Not Found");
        }
    }



    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doDispatcher(req, resp);
    }
}


3.3 总结


在 spring 中运用到委派模式的地方还有很多,可以通过命名识别出来,在 Spring 源码中,以 Delegate 结尾的地方都实现类委派模式,例如 BeanDefinitionParserDelegate 根据不同类型委派不同的逻辑解析 BeanDefinition