設(shè)計模式——委派模式

委派模式

在設(shè)計模式中虫腋,似乎沒有委派模式這一模式,就想魯迅說的稀余,世界上本么沒有路悦冀,走的人多了便成了路。正是因為這種邏輯被多次用到睛琳,便被前人總結(jié)為委派設(shè)計模式盒蟆。
委派模式(Delegate Pattern)的作用就是負(fù)責(zé)任務(wù)的調(diào)度和分配任務(wù),跟代理模式很像师骗,可以看做是一種特殊情況下的靜態(tài)代理的全權(quán)代理历等,但是代理注重過程,而委派模式注重結(jié)果辟癌。

委派模式跟我們程序員的生態(tài)圈非常像寒屯,需求來了,項目經(jīng)理根據(jù)程序員的能力來進行分配愿待,這個的過程就是委派浩螺,對于提出需求的人來說,我們程序員是不可見的仍侥。

舉一個簡單的例子
1、創(chuàng)建程序員接口和程序員

public interface Employee {
    void doing(String command);
}
public class ProgramerA implements Employee{

    @Override
    public void doing(String command){
        System.out.println("我擅長加密:我正在做:"+command);
    }
}
public class ProgramerB implements Employee{

    @Override
    public void doing(String command){

        System.out.println("我擅長架構(gòu):我正在做:"+command);
    }
}

2鸳君、創(chuàng)建項目經(jīng)理

public class Leader {
    // 預(yù)先知道每個員工的特長农渊、特征、分發(fā)任務(wù)
    Map<String,Employee> register = new HashMap<>();

    public Leader(){
        register.put("加密",new ProgramerA());
        register.put("架構(gòu)",new ProgramerB());
    }

    public void doing(String command){
            register.get(command).doing(command);
    }
}

3或颊、創(chuàng)建甲方用戶,用戶只與leader聯(lián)系

public class Customer {

    public void command(String command, Leader leader){
        leader.doing(command);
    }
}

4砸紊、測試
用戶有一個加密任務(wù)交給項目經(jīng)理,項目經(jīng)理進行委派

public class AppTest {
    public static void main(String[] args) {
        new Customer().command("加密",new Leader());
    }
}

我擅長加密:我正在做:加密

類圖

image.png

從類圖中可以看出Leader是作為中間人協(xié)調(diào)用戶的任務(wù)和程序員的工作的囱挑。而且類圖中也提現(xiàn)了與靜態(tài)代理的區(qū)別醉顽,Leader只是依賴接口,并不繼承接口平挑。一般地游添,帶有delegate或者dispatcher都可以先聯(lián)想委派模式。

比如我們熟悉的DispatherServlet通熄,SpringMVC中負(fù)責(zé)請求分發(fā)處理的唆涝,我們只需關(guān)注它的dispatch方法
doDispatch() 方法進行請求分發(fā)處理,doDispatch() 方法的主要過程是通過 HandlerMapping 獲取 Handler唇辨,再找到用于執(zhí)行它的 HandlerAdapter廊酣,執(zhí)行 Handler 后得到 ModelAndView ,ModelAndView 是連接“業(yè)務(wù)邏輯層”與“視圖展示層”的橋梁赏枚,接下來就要通過 ModelAndView 獲得 View亡驰,再通過它的 Model 對 View 進行渲染晓猛。想深入研究DispatcherServlet可以去看這篇文章,寫的很好DispatcherServlet詳解
這里可以關(guān)注第21行凡辱,這里就是委派模式的體現(xiàn)

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    // 獲取當(dāng)前請求的WebAsyncManager戒职,如果沒找到則創(chuàng)建并與請求關(guān)聯(lián)
    WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
    try {
        ModelAndView mv = null;
        Exception dispatchException = null;
        try {
            // 檢查是否有 Multipart,有則將請求轉(zhuǎn)換為 Multipart 請求
            processedRequest = checkMultipart(request);
            multipartRequestParsed = (processedRequest != request);
            // 遍歷所有的 HandlerMapping 找到與請求對應(yīng)的 Handler煞茫,并將其與一堆攔截器封裝到 HandlerExecution 對象中帕涌。
            mappedHandler = getHandler(processedRequest);
            if (mappedHandler == null || mappedHandler.getHandler() == null) {
                noHandlerFound(processedRequest, response);
                return;
            }
            // 遍歷所有的 HandlerAdapter,找到可以處理該 Handler 的 HandlerAdapter
            HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
            // 處理 last-modified 請求頭 
            String method = request.getMethod();
            boolean isGet = "GET".equals(method);
            if (isGet || "HEAD".equals(method)) {
                long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                    return;
                }
            }
            // 遍歷攔截器续徽,執(zhí)行它們的 preHandle() 方法
            if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                return;
            }
            try {
                // 執(zhí)行實際的處理程序
                mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
            } finally {
                if (asyncManager.isConcurrentHandlingStarted()) {
                    return;
                }
            }
            applyDefaultViewName(request, mv);
            // 遍歷攔截器王浴,執(zhí)行它們的 postHandle() 方法
            mappedHandler.applyPostHandle(processedRequest, response, mv);
        } catch (Exception ex) {
            dispatchException = ex;
        }
        // 處理執(zhí)行結(jié)果蹲嚣,是一個 ModelAndView 或 Exception,然后進行渲染
        processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    } catch (Exception ex) {
    } catch (Error err) {
    } finally {
        if (asyncManager.isConcurrentHandlingStarted()) {
            // 遍歷攔截器,執(zhí)行它們的 afterCompletion() 方法  
            mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
            return;
        }
        // Clean up any resources used by a multipart request.
        if (multipartRequestParsed) {
            cleanupMultipart(processedRequest);
        }
    }
}  
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末胶征,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子迅细,更是在濱河造成了極大的恐慌衅谷,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件膀斋,死亡現(xiàn)場離奇詭異梭伐,居然都是意外死亡,警方通過查閱死者的電腦和手機仰担,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評論 3 385
  • 文/潘曉璐 我一進店門糊识,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人摔蓝,你說我怎么就攤上這事赂苗。” “怎么了贮尉?”我有些...
    開封第一講書人閱讀 157,490評論 0 348
  • 文/不壞的土叔 我叫張陵拌滋,是天一觀的道長。 經(jīng)常有香客問我猜谚,道長败砂,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評論 1 284
  • 正文 為了忘掉前任龄毡,我火速辦了婚禮吠卷,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘沦零。我一直安慰自己祭隔,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,627評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著疾渴,像睡著了一般千贯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上搞坝,一...
    開封第一講書人閱讀 49,842評論 1 290
  • 那天搔谴,我揣著相機與錄音,去河邊找鬼桩撮。 笑死敦第,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的店量。 我是一名探鬼主播芜果,決...
    沈念sama閱讀 38,997評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼融师!你這毒婦竟也來了右钾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評論 0 268
  • 序言:老撾萬榮一對情侶失蹤旱爆,失蹤者是張志新(化名)和其女友劉穎舀射,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體怀伦,經(jīng)...
    沈念sama閱讀 44,203評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡脆烟,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,534評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了房待。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片浩淘。...
    茶點故事閱讀 38,673評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖吴攒,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情砂蔽,我是刑警寧澤洼怔,帶...
    沈念sama閱讀 34,339評論 4 330
  • 正文 年R本政府宣布,位于F島的核電站左驾,受9級特大地震影響镣隶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜诡右,卻給世界環(huán)境...
    茶點故事閱讀 39,955評論 3 313
  • 文/蒙蒙 一安岂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧帆吻,春花似錦域那、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽败许。三九已至,卻和暖如春淑蔚,著一層夾襖步出監(jiān)牢的瞬間市殷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評論 1 266
  • 我被黑心中介騙來泰國打工刹衫, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留醋寝,地道東北人。 一個月前我還...
    沈念sama閱讀 46,394評論 2 360
  • 正文 我出身青樓带迟,卻偏偏與公主長得像音羞,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子邮旷,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,562評論 2 349

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