(8)spring常用模式--------委派模式

1.委派模式簡介

在常用的23種設(shè)計模式中其實面沒有委派模式(delegate)的影子,但是在Spring中委派模式確實用的比較多的一種模式。

在spring中的體現(xiàn):Spring MVC框架中的DispatcherServlet其實就用到了委派模式。

委派模式的作用: 基本作用就是負責(zé)任務(wù)的調(diào)用和分配任務(wù),跟代理模式很像,可以看做是一種特殊情況下的靜態(tài)代理的全權(quán)代理,但是代理模式注重過程,而委派模式注重結(jié)果

2.委派模式的實例

先引用一張圖來介紹委派模式,下圖主要說明了 boss把任務(wù)給leader,而leader做了一個任務(wù)的分配和調(diào)度的工作,自己沒有做工作,而是把具體工作交給具體的執(zhí)行者去做。

委派模式.png

下面直接給出實例:

執(zhí)行的接口

/**
 * @Project: spring
 * @description: 執(zhí)行的接口
 * @author: sunkang
 * @create: 2018-08-30 23:10
 * @ModificationHistory who      when       What
 **/
public interface IExcuter {
    void excute(String command);
}

普通員工A

/**
 * @Project: spring
 * @description: 員工A執(zhí)行某項命令
 * @author: sunkang
 * @create: 2018-08-30 23:10
 * @ModificationHistory who      when       What
 **/
public class ExcuterA implements  IExcuter{

    @Override
    public void excute(String command) {
        System.out.println("員工A 開始做"+command+"的工作");
    }
}

普通員工B

/**
 * @Project: spring
 * @description: 員工B執(zhí)行某項命令
 * @author: sunkang
 * @create: 2018-08-30 23:10
 * @ModificationHistory who      when       What
 **/
public class ExcuterB implements  IExcuter{
    @Override
    public void excute(String command) {
        System.out.println("員工B 開始做"+command+"的工作");
}
}

leader委派者

/**
 * @Project: spring
 * @description:    leader 委派者   任務(wù)分發(fā)的作用
 * @author: sunkang
 * @create: 2018-08-30 23:11
 * @ModificationHistory who      when       What
 **/
public class Leader implements  IExcuter {

    private Map<String,IExcuter> targets = new HashMap<String,IExcuter>();
    public Leader() {
        targets.put("加密",new ExcuterA());
        targets.put("登錄",new ExcuterB());
    }
    @Override
    public void excute(String command) {
        targets.get(command).excute(command);
    }
}

boss類模擬調(diào)用測試

/**
 * @Project: spring
 * @description:  boss  模擬客戶執(zhí)行任務(wù)
 * @author: sunkang
 * @create: 2018-08-30 23:13
 * @ModificationHistory who      when       What
 **/
public class Boss
{
    public static void main(String[] args) {
        Leader leader  = new Leader();
        //看上去好像是我們的項目經(jīng)理在干活
        //但實際干活的人是普通員工
        //這就是典型,干活是我的,功勞是你的
        leader.excute("登錄");
        leader.excute("加密");
    }
}

測試結(jié)果為:

委派模式測試結(jié)果.png

3.委派模式的實現(xiàn)mvc的簡單實例

思考:
在springmvc 訪問地址的urlController層配置的url是如何映射的
Controller層配置的url如何跟具體的方法映射的,參數(shù)又是如何綁定

猜測:
url的地址可以根據(jù)request得到訪問url地址,配置的url地址可以根據(jù)配置注解得到,這兩者的url匹配上了說明映射成功了,除了url是不夠的,還需要一個中間對象保存了url和method以及controller對象的信息,可以把這個中年的映射對象放入容器中,然后根據(jù)傳入的url從容器取出進行匹配,取出來之后就可以根據(jù)映射來完成方法的調(diào)用了。

下面就簡單實現(xiàn)一個mvc調(diào)用的例子
模擬controller層

/**
 * @Project: spring
 * @description:  模擬controller層
 * @author: sunkang
 * @create: 2018-09-03 22:20
 * @ModificationHistory who      when       What
 **/
public class MemberAction {

    public void getMemberById(String mid){
        
    }
}

模擬serlvert得到的請求如何轉(zhuǎn)發(fā),交給具體的controller處理的

/**
 * @Project: spring
 * @description:   selvelt的任務(wù)分發(fā)者 ,主要完成url的映射和調(diào)用
 * @author: sunkang
 * @create: 2018-09-03 22:21
 * @ModificationHistory who      when       What
 **/
public class SelvletDispatcher {
    //這里也可以用map 對象來保存Hanlder對象
    private List<Handler> handlerMapping = new ArrayList<Handler>();
    
    public SelvletDispatcher() {
        //簡單實現(xiàn)一個controller的映射
        try {
      Class clazz  = MemberAction.class;

            handlerMapping.add(new Handler()
                            .setController(clazz.newInstance())
                            .setMethod(clazz.getMethod("getMemberById",new Class[]{String.class}))
                            .setUrl("/web/getMemberById.json")
            );
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

    /**
     * 請求的分發(fā)工作
     * @param request
     * @param response
     */
    private void doDispatch(HttpServletRequest request, HttpServletResponse response) {
      //1.獲取用戶請求的url
      String uri =   request.getRequestURI();
      Handler handler =null;

      ////2、根據(jù)uri 去handlerMapping找到對應(yīng)的hanler
      for(Handler h :handlerMapping){
          if(uri.equals(h.getUrl())){
              handler = h;
              break;
          }
      }
      //3.將具體的任務(wù)分發(fā)給Method(通過反射去調(diào)用其對應(yīng)的方法)
        Object obj = null;
        try {
            obj =  handler.getMethod().invoke(handler.getController(),request.getParameter("mid"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        //4、獲取到Method執(zhí)行的結(jié)果,通過Response返回出去
        // response.getWriter().write();

    }
    /**
     * 具體的hanlder對象
     */
    class Handler{
        //controller對象
        private Object controller;
        //controller對象映射的方法
        private  String url;
        //ulr對應(yīng)的方法
        private Method method;

        public Object getController() {
            return controller;
        }

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

        public String getUrl() {
            return url;
        }

        public Handler setUrl(String url) {
            this.url = url;
            return  this;
        }

        public Method getMethod() {
            return method;
        }

        public Handler setMethod(Method method) {
            this.method = method;
            return this;
        }
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容