设计模式之委派模式(Delegate Pattern)深入浅出

学习目标:精简程序逻辑,提升代码的可读性。

内容定位:希望通过对委派模式的学习,让自己写出更加优雅的代码的人群。

委派模式定义:

  • 委派模式(Delegate Pattern)的基本作用是负责任务的调度和分配任务,跟代理模式很像,可以看作是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。
  • 不属于GOF 23中设计模式之一
  • 属于行为型模式

 常见应用场景案例:

  • DispatcherServlet
  • 类名以Delegate结尾的
  • 包含Dispatcher的一般都是委派模式
  • Spring框架IOC中的BeanDefinitionParserDelegate:Spring提供多种方式(java、xml、注解)配置bean,该类负责分发处理,注入的bean信息最终会被加载为一个BeanDefition对象(描述对象信息)

 应用场景:解决多任务,又不希望把这些任务或者具体的实现让用户知道(不让用户直接交互),创建一个中间类,实现全权代理,达到对用户来说只有一个入口的目的。

简单代码案例

例子:老板需要安排任务给员工,但是又不能直接让老板去了解每个员工的擅长职能,就可以创建一个中间的经理职位负责了解职员的特长,分发任务。

boss类

/**
 * @ClassName Boss
 * @Author 周聪
 * @Date 2021/1/9 15:48
 * @Version 1.0
 * @Description 老板发布命令
 */
public class Boss {

    /**
     * 发任务
     * @param command
     * @param leader
     */
    public void command(String command,Leader leader){
        leader.doing(command);
    }
}

经理类

/**
 * @ClassName Leader
 * @Author 周聪
 * @Date 2021/1/9 16:04
 * @Version 1.0
 * @Description 项目经理
 */
public class Leader {
//    预先知道每个员工的特长、特征,分发任务
    private Map<String,IEmployee> register = new HashMap<String,IEmployee>();

    public Leader(){
        register.put("加密",new EmployeeA());
        register.put("架构",new EmployeeB());
    }

    public void doing(String command){
//        交给指定的员工去做
        register.get(command).doing(command);
    }
}

员工接口

/**
 * @ClassName IEmployee
 * @Author 周聪
 * @Date 2021/1/9 16:05
 * @Version 1.0
 * @Description 员工接口
 */
public interface IEmployee {

    /**
     * 做事
     * @param command
     */
    void doing(String command);
}

员工A

/**
 * @ClassName EmployeeA
 * @Author 周聪
 * @Date 2021/1/9 16:07
 * @Version 1.0
 * @Description 员工A
 */
public class EmployeeA implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是员工A,我开始干活了,我擅长加密,执行");
    }
}

员工B

/**
 * @ClassName EmployeeB
 * @Author 周聪
 * @Date 2021/1/9 16:09
 * @Version 1.0
 * @Description 员工B
 */
public class EmployeeB implements IEmployee {
    @Override
    public void doing(String command) {
        System.out.println("我是员工B,我擅长架构,我开始干活了");
    }
}

测试类

/**
 * @ClassName DelegateTest
 * @Author 周聪
 * @Date 2021/1/9 16:18
 * @Version 1.0
 * @Description
 */
public class DelegateTest {

    public static void main(String[] args) {
        new Boss().command("架构",new Leader());
    }
}

SpringMvc的DispatcherServlet简单实现

DispatcherServlet是前端控制器委派模式的实现,提供Spring Web MVC的集中访问点,负责职责的分派

web.xml

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>Archetype Created Web Application</display-name>

  <servlet>
    <servlet-name>delegateServlet</servlet-name>
    <servlet-class>com.zc.pattern.delegate.mvc.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
    <servlet-name>delegateServlet</servlet-name>
    <url-pattern>/*</url-pattern>
  </servlet-mapping>

<!--  http://localhost:8080/getMemberById.do -->

</web-app>

DispatcherServlet

package com.zc.pattern.delegate.mvc;

import com.zc.pattern.delegate.mvc.controllers.MemberController;
import com.zc.pattern.delegate.mvc.controllers.OrderController;
import com.zc.pattern.delegate.mvc.controllers.SystemController;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @ClassName DispatcherServlet
 * @Author 周聪
 * @Date 2021/1/9 16:31
 * @Version 1.0
 * @Description
 */
public class DispatcherServlet extends HttpServlet {

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//        完成调度
        doDispach(req,resp);
    }

    private void doDispach(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        String uri = req.getRequestURI();
        if ("getMemberById".equals(uri)){
            String mid = req.getParameter("mid");
            new MemberController().getMemberById(mid);
        }else if ("getOrderById".equals(uri)){
            String oid = req.getParameter("oid");
            new OrderController().getOrderById(oid);
        }else if ("getSystemById".equals(uri)){
            new SystemController().logout();
        }else {
            resp.getWriter().write("404 not found");
        }
    }
}

MemberController

/**
 * @ClassName MemberController
 * @Author 周聪
 * @Date 2021/1/9 17:09
 * @Version 1.0
 * @Description
 */
public class MemberController {

    public void getMemberById(String mid){
        System.out.println("获取员工id");
    }
}
OrderController 
/**
 * @ClassName OrderController
 * @Author 周聪
 * @Date 2021/1/9 17:10
 * @Version 1.0
 * @Description
 */
public class OrderController {

    public void getOrderById(String oid){
        System.out.println("获取订单id");
    }
}
SystemController 
/**
 * @ClassName SystemController
 * @Author 周聪
 * @Date 2021/1/9 17:11
 * @Version 1.0
 * @Description
 */
public class SystemController {

    public void logout(){
        System.out.println("退出");
    }
}

以上对单例模式的介绍到此结束,欢迎批评指正。 附:源码地址

上一篇:龙头装饰靠谱么,C# 委托(Delegate)


下一篇:jQuery中delegate()方法详解