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

1.委派模式簡(jiǎn)介

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

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

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

2.委派模式的實(shí)例

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

委派模式.png

下面直接給出實(shí)例:

執(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í)行某項(xiàng)命令
 * @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í)行某項(xiàng)命令
 * @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)用測(cè)試

/**
 * @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();
        //看上去好像是我們的項(xiàng)目經(jīng)理在干活
        //但實(shí)際干活的人是普通員工
        //這就是典型,干活是我的壕鹉,功勞是你的
        leader.excute("登錄");
        leader.excute("加密");
    }
}

測(cè)試結(jié)果為:

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

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

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

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

下面就簡(jiǎn)單實(shí)現(xiàn)一個(gè)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得到的請(qǐng)求如何轉(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 對(duì)象來保存Hanlder對(duì)象
    private List<Handler> handlerMapping = new ArrayList<Handler>();
    
    public SelvletDispatcher() {
        //簡(jiǎn)單實(shí)現(xiàn)一個(gè)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);
    }

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

      ////2础芍、根據(jù)uri 去handlerMapping找到對(duì)應(yīng)的hanler
      for(Handler h :handlerMapping){
          if(uri.equals(h.getUrl())){
              handler = h;
              break;
          }
      }
      //3.將具體的任務(wù)分發(fā)給Method(通過反射去調(diào)用其對(duì)應(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對(duì)象
     */
    class Handler{
        //controller對(duì)象
        private Object controller;
        //controller對(duì)象映射的方法
        private  String url;
        //ulr對(duì)應(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)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末仑性,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子右蹦,更是在濱河造成了極大的恐慌诊杆,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,430評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件何陆,死亡現(xiàn)場(chǎng)離奇詭異晨汹,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贷盲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,406評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門淘这,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巩剖,你說我怎么就攤上這事铝穷。” “怎么了佳魔?”我有些...
    開封第一講書人閱讀 167,834評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵氧骤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我吃引,道長(zhǎng)筹陵,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,543評(píng)論 1 296
  • 正文 為了忘掉前任镊尺,我火速辦了婚禮朦佩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘庐氮。我一直安慰自己语稠,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,547評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著仙畦,像睡著了一般输涕。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上慨畸,一...
    開封第一講書人閱讀 52,196評(píng)論 1 308
  • 那天莱坎,我揣著相機(jī)與錄音,去河邊找鬼寸士。 笑死檐什,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的弱卡。 我是一名探鬼主播乃正,決...
    沈念sama閱讀 40,776評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼婶博!你這毒婦竟也來了瓮具?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,671評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤凡人,失蹤者是張志新(化名)和其女友劉穎名党,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體划栓,經(jīng)...
    沈念sama閱讀 46,221評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,303評(píng)論 3 340
  • 正文 我和宋清朗相戀三年条获,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了忠荞。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,444評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡帅掘,死狀恐怖委煤,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情修档,我是刑警寧澤碧绞,帶...
    沈念sama閱讀 36,134評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站吱窝,受9級(jí)特大地震影響讥邻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜院峡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,810評(píng)論 3 333
  • 文/蒙蒙 一兴使、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧照激,春花似錦发魄、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,285評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)汰寓。三九已至,卻和暖如春苹粟,著一層夾襖步出監(jiān)牢的瞬間有滑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,399評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工六水, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留俺孙,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,837評(píng)論 3 376
  • 正文 我出身青樓掷贾,卻偏偏與公主長(zhǎng)得像睛榄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子想帅,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,455評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容