java设计模式————委派模式,天天使用却不知道的模式,手撸spring

委派模式(Delegate Pattern):

基本作用就是负责任务的调度和分配任务,跟代理模式很像,可以看做是一种特殊情况下的静态代理的全权代理,但是代理模式注重过程,而委派模式注重结果。

不属于gof23种设计模式之一。

属于行为型模式。

现实场景:

老板要做一些事情,只需要交代给经理,由经理分发给对应的员工即可

代码:

/**
 * @Author Darker
 * @Descrption 老板
 * @Date : Created in 10:37 2020-3-12
 */
public class Boss {

    //委派什么任务给经理
    public void delegate(String task,Leader leader){
        leader.doing(task);
    }
}

/**
 * @Author Darker
 * @Descrption  被委派的经理,存储他统管的所有员工
 * @Date : Created in 10:37 2020-3-12
 */
public class Leader {
    //要知道每个员工的特长何特征
    private Map<String,IEmployee> register = new HashMap<>();

    public Leader(){
        register.put("数据库",new Aemployee());
        register.put("业务逻辑",new Bemployee());
    }

    //分配对应的任务给对应的员工
    public void doing(String task){
        register.get(task).doingSomeThings(task);
    }
}

/**
 * @Author Darker
 * @Descrption 员工抽象
 * @Date : Created in 10:38 2020-3-12
 */
public interface IEmployee {

    public void doingSomeThings(String task);
}

/**
 * @Author Darker
 * @Descrption
 * @Date : Created in 10:39 2020-3-12
 */
public class Aemployee implements IEmployee{
    @Override
    public void doingSomeThings(String task) {
        System.out.println("我是a员工,我负责做数据库的工作,我做了"+task+"任务");
    }
}

/**
 * @Author Darker
 * @Descrption
 * @Date : Created in 10:40 2020-3-12
 */
public class Bemployee implements IEmployee{
    @Override
    public void doingSomeThings(String task) {
        System.out.println("我是b员工,我负责做业务开发的工作,我做了"+task+"任务");
    }
}

 执行结果:

现在老板需要委派一个数据库的任务给经理,获得反馈

/**
 * @Author Darker
 * @Descrption
 * @Date : Created in 10:57 2020-3-12
 */
public class DelegateTest {
    public static void main(String[] args) {
        new Boss().delegate("数据库",new Leader());
    }
}

 

分析一下,老板相当于需求,现在有一个经理类来帮老板分发任务,所以经理需要知道所有员工,以及每个员工对应的任务,用一个私有的map存了所有员工以及对应的任务,当收到一个任务时,可以很快的安排对应的任务给对应的员工,这种模式有点像静态代理。

扫描二维码关注公众号,回复: 9841462 查看本文章

类之间的关系:

那么问题来了,我们写代码到底在哪里会用到委派模式呢,不急我们先来看一段代码,看完你就知道了。

/**
 * @Author Darker
 * @Descrption 请求处理Servlet
 * @Date : Created in 11:14 2020-3-12
 */
public class DispatcherServlet extends HttpServlet{

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

    public void delegate(HttpServletRequest req, HttpServletResponse resp){
        String reqUrl = req.getRequestURI();

        if ("getOrderById".equals(reqUrl)){
            new OrderController().getOrderById();
        }else if("logout".equals(reqUrl)){
            new SystemController().logout();
        }else{
            System.out.println("访问路径不存在 404");
        }
    }
}

/**
 * @Author Darker
 * @Descrption 订单业务Controller
 * @Date : Created in 11:15 2020-3-12
 */
public class OrderController {

    public void getOrderById(){

    }
}

/**
 * @Author Darker
 * @Descrption 系统操作Controller
 * @Date : Created in 11:28 2020-3-12
 */
public class SystemController {

    public void logout(){

    }
}

发现了没有,我们浏览器输入的访问地址都是走servlet,然后servlet来帮我们分派到你要调用的service中并且决定调用哪一个方法,这是不是就是策略模式呢,我们上面写的代码就是一个简易的分配逻辑。

好了,这就是委派模式了,它是一种比较简单的设计模式,但是和其它模式结合在一起也对代码的优化起到了不可忽视的作用。

补充:

上面最后的处理有点粗糙,所以本人参考spring的源码又做了些补充,是学习spring的思想来写的,下面是改进后的代码。

/**
 * @Author Darker
 * @Descrption 请求处理Servlet
 * @Date : Created in 11:14 2020-3-12
 */
public class DispatcherServlet extends HttpServlet{

    private List<Handler> handlerMapping = new ArrayList<>();

    
    //初始化的时候把controller和访问路径,方法绑定在一个list里面
    @Override
    public void init() throws ServletException {
        Class<?> orderControllerClass =  OrderController.class;
        try {
            handlerMapping.add(new Handler()
                            .setController(orderControllerClass.newInstance())
                            .setMeThod(orderControllerClass.getMethod("getOrderById"))
                            .setUrl("/web/getMemberById.json")
                                );
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

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

    public void delegate(HttpServletRequest req, HttpServletResponse resp){
        String reqUrl = req.getRequestURI();
        Handler handler = null;
        for(Handler h :handlerMapping){
            if(reqUrl.equals(h.getUrl())){
                handler = h;
                break;
            }
        }

        try {
            Object o = handler.getMeThod().invoke(handler.getController(),null);
            try {
                resp.getWriter().write(o.toString());
            } catch (IOException e) {
                e.printStackTrace();
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }



       /* if ("getOrderById".equals(reqUrl)){
            new OrderController().getOrderById();
        }else if("logout".equals(reqUrl)){
            new SystemController().logout();
        }else{
            System.out.println("访问路径不存在 404");
        }*/
    }

    //绑定的类,模仿lombok的链式调用
    class Handler{
        private  Object controller;
        private Method meThod;
        private String url;

        public Object getController() {
            return controller;
        }

        public Handler setController(Object controller) {
            this.controller = controller;
            return this;
        }

        public Method getMeThod() {
            return meThod;
        }

        public Handler setMeThod(Method meThod) {
            this.meThod = meThod;
            return this;
        }

        public String getUrl() {
            return url;
        }

        public Handler setUrl(String url) {
            this.url = url;
            return this;
        }
    }
}
发布了27 篇原创文章 · 获赞 1 · 访问量 3643

猜你喜欢

转载自blog.csdn.net/qq_40111437/article/details/104811403