设计模式之委派模式(不属于23种经典设计模式之一)

介绍

标准定义:委派模式的原理为类B和类A是两个互相没有任何关系的类,B具有和A一模一样的方法和属性,并且调用B中的方法、属性就是调用A中同名的方法和属性。B好像就是一个受A授权委托的中介。第三方的代码不需要知道A的存在,也不需要和A发生直接的联系,通过B就可以直接使用A的功能,这样既能够使用到A的各种功能,又能够很好的将A保护起来,一举两得。
通俗理解:我们在项目开发中都是一个项目团队,老板把任务交给项目经理后,项目经理制定项目计划、将任务下发到底下的开发人员,这就是委派模式。但是我们发现这个跟之前学的代理模式非常相似,其实这也可以当做是静态代理模式的一种特例。此外,项目经理接到任务后会做一个权衡,怎么去选择分配这些任务。我们又发现这个跟之前学的策略模式非常相似,其实这也可以当做是策略模式的一种特例。(其实设计模式一般都不会独立存在,都是混合使用)
委派模式跟静态代理模式以及策略模式的区别?
委派模式:代理人全权负责这一件事。如:老板给项目经理安排任务,项目经理只是负责调度工作,真正干活的是底下的开发人员。
静态代理模式:代理人只是参与被代理人一小部分的工作,最终的结论还是得由代理人来决定。如:张三没空找对象,媒婆帮张三物色到一个对象,最终得看张三喜不喜欢这个对象。
策略模式:项目经理在分配任务的时候需要权衡,会产生多种分配方案,但是最终都是将手中的任务分配给底下的开发人员。

案例

场景: springmvc框架中的DispatcherServlet其实就是一个典型的委派模式。
代码:
1>假设有以下三个action,每个action执行不同的业务操作。

public class MemberAction {
    public void getMemberById(String mid){

    }
}
public class OrderAction {
    public void getOrderById(String mid){

    } 
}
public class SystemAction {
    public void logout(String mid){

    }
}

2>真实的分发类

//这个类对客户端发来的请求做分发(类似项目经理分配任务)
public class ServletDispatcher {
    private List<Handler> handlerMapping=new ArrayList<Handler>();
    public ServletDispatcher(List<Handler> handlerMapping) {
        try{
            Class<?> memberActionClass=MemberAction.class;
            handlerMapping.add(new Handler()
                    .setController(memberActionClass.newInstance())
                    .setMethod(memberActionClass.getMethod("getMemberById",new Class[]{String.class}))
                    .setUrl("/web/getMemberById.json"));
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public void doService(HttpServletRequest request, HttpServletResponse response){
        doDispatch(request,response);
    }

    private void doDispatch(HttpServletRequest request, HttpServletResponse response){
        //1.获取用户请求的url
        //如果按照j2ee标准,每个url会对应一个servlet,url由浏览器输入
        //而现在使用委派模式,就只需要配一个url,其他的都交给该类统一管理
        String uri=request.getRequestURI();
        //2.servlet拿到url以后要做权衡(要做判断、要做选择)
        //根据用户请求的url,去找到这个url对应的某一个java类的方法

        //3.通过拿到的url去handlerMapping中找(我们把它认为是策略常量)
        Handler handler=null;
        for(Handler h:handlerMapping){
            if(uri.equals(h.getUrl())){
                handler=h;
                break;
            }
        }
        //4.将具体的任务分发给method(通过反射去调用其对应的方法)
        Object object=null;
        try {
            object=handler.getMethod().invoke(handler.getController(),request.getParameter("mid"));
        }catch (Exception e){
            e.printStackTrace();
        }

        //5.获取到method的执行结果,通过response返回出去
//        response.getWriter().write();
    }

    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;
        }
    }
}

总结:委派模式在spring中应用十分广泛,但是它本身不属于23种经典设计模式。

猜你喜欢

转载自blog.csdn.net/fu123123fu/article/details/80159551