職責鏈
1.概述
? ? ? ?你去政府部門求人辦事過嗎桶蝎?有時候你會遇到過官員踢球推責坐儿,你的問題在我這里能解決就解決,不能解決就推卸給另外個一個部門(對象)。至于到底誰來解決這個問題呢溢陪?政府部門就是為了可以避免屁民的請求與官員之間耦合在一起他炊,讓多個(部門)對象都有可能接收請求盯孙,將這些(部門)對象連接成一條鏈羽利,并且沿著這條鏈傳遞請求,直到有(部門)對象處理它為止序苏。
例子1:js的事件浮升機制
例子2:
2.問題
如果有多個對象都有可能接受請求手幢,如何避免避免請求發(fā)送者與接收者耦合在一起呢?
3.解決方案
職責鏈模式(Chain of Responsibility):使多個對象都有機會處理請求忱详,從而避免請求的發(fā)送者和接收者之間的耦合關系围来。將這些對象連成一條鏈,并沿著這條鏈傳遞該請求匈睁,直到有一個對象處理它為止监透。(Avoid coupling the sender of a request to itsreceiver by giving morethan one objecta chance to handle the request.Chain the receiving objects andpassthe request along the chain until an object handles it.?)
1)在職責鏈模式里,很多對象由每一個對象對其下家的引用而連接起來形成一條鏈航唆。2)請求在這條鏈上傳遞胀蛮,直到鏈上的某一個對象處理此請求為止。3)發(fā)出這個請求的客戶端并不知道鏈上的哪一個對象最終處理這個請求糯钙,這使得系統(tǒng)可以在不影響客戶端的情況下動態(tài)地重新組織鏈和分配責任粪狼。
4.適用性
在以下條件下使用Responsibility 鏈:
? 有多個的對象可以處理一個請求退腥,哪個對象處理該請求運行時刻自動確定。
? 你想在不明確指定接收者的情況下再榄,向多個對象中的一個提交一個請求狡刘。
?可動態(tài)指定一組對象處理請求。
5.結構
一個典型的對象結構可能如下圖所示:
6. 模式的組成
抽象處理者角色(Handler:Approver):定義一個處理請求的接口困鸥,和一個后繼連接(可選)
具體處理者角色(ConcreteHandler:President):處理它所負責的請求嗅蔬,可以訪問后繼者,如果可以處理請求則處理窝革,否則將該請求轉給他的后繼者购城。
客戶類(Client):向一個鏈上的具體處理者ConcreteHandler對象提交請求。
7. 效果
Responsibility 鏈有下列優(yōu)點和缺點( l i a b i l i t i e s ) :
職責鏈模式的優(yōu)點:
1 ) 降低耦合度 :該模式使得一個對象無需知道是其他哪一個對象處理其請求虐译。對象僅需知道該請求會被“正確”地處理。接收者和發(fā)送者都沒有對方的明確的信息吴趴,且鏈中的對象不需知道鏈的結構漆诽。
2)?職責鏈可簡化對象的相互連接?: ? ?結果是,職責鏈可簡化對象的相互連接锣枝。它們僅需保持一個指向其后繼者的引用厢拭,而不需保持它所有的候選接受者的引用。
3) 增強了給對象指派職責( R e s p o n s i b i l i t y )的靈活性?:當在對象中分派職責時撇叁,職責鏈給你更多的靈活性供鸠。你可以通過在運行時刻對該鏈進行動態(tài)的增加或修改來增加或改變處理一個請求的那些職責。你可以將這種機制與靜態(tài)的特例化處理對象的繼承機制結合起來使用陨闹。
4)增加新的請求處理類很方便
職責鏈模式的缺點:1) ??不能保證請求一定被接收楞捂。既然一個請求沒有明確的接收者,那么就不能保證它一定會被處理 —該請求可能一直到鏈的末端都得不到處理趋厉。一個請求也可能因該鏈沒有被正確配置而得不到處理寨闹。2) ??系統(tǒng)性能將受到一定影響,而且在進行代碼調試時不太方便君账;可能會造成循環(huán)調用繁堡。
8. 純與不純的職責鏈模式
純的職責鏈模式:一個具體處理者角色處理只能對請求作出兩種行為中的一個:一個是自己處理(承擔責任),另一個是把責任推給下家乡数。不允許出現某一個具體處理者對象在承擔了一部分責任后又將責任向下傳的情況椭蹄。請求在責任鏈中必須被處理,不能出現無果而終的結局净赴。反之就是不純的職責鏈模式绳矩。??在一個純的職責鏈模式里面,一個請求必須被某一個處理者對象所接收劫侧;在一個不純的職責鏈模式里面埋酬,一個請求可以最終不被任何接收端對象所接收哨啃。
9.實現
我們先來看不純的職責模式:
假如在公司里,
如果你的請假時間小于0.5天写妥,那么只需要向leader打聲招呼就OK了拳球。
如果0.5<請假天數<=3天,需要先leader打聲招呼珍特,要不然leader不知你跑哪里祝峻,然后部門經理直接簽字。
如果3<請假天數 天扎筒,需要先leader打聲招呼莱找,然后到部門經理簽字,最好總經經理確認簽字嗜桌,當你看到這情況后你心里是不是已經有了自己的想法了?寫一系列的if語句來一條條的判斷.但這樣的寫法雖然可以實現目前的需求,可如果當流程改了呢奥溺?我請假超過3天,告訴leader和總經理簽字就可以骨宠,那你又得一步一步修改程序浮定。如果if語句的條數發(fā)生變化的話我們還必須在代碼中添加必要的if判斷,這對于程序的維護來說是相當麻煩的.如果我們使用職責鏈模式的話就可以相當簡單了.
命令模式
目的:
任何模式的出現层亿,都是為了解決一些特定的場景的耦合問題桦卒,以達到對修改封閉,對擴展開放的效果匿又。命令模式也不例外:
命令模式是為了解決命令的請求者和命令的實現者之間的耦合關系方灾。
解決了這種耦合的好處我認為主要有兩點:
1.更方便的對命令進行擴展(注意:這不是主要的優(yōu)勢,后面會提到)
2.對多個命令的統(tǒng)一控制(這種控制包括但不限于:隊列碌更、撤銷/恢復裕偿、記錄日志等等)
模式解析:
經典的命令模式包括4個角色:
Command:定義命令的統(tǒng)一接口
ConcreteCommand:Command接口的實現者,用來執(zhí)行具體的命令针贬,某些情況下可以直接用來充當Receiver击费。
Receiver:命令的實際執(zhí)行者
Invoker:命令的請求者,是命令模式中最重要的角色桦他。這個角色用來對各個命令進行控制
訪問器
訪問者模式就是表示一個作用于某對象結構中的各元素的操作蔫巩。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。?
類圖和樣例:
抽象訪問者(Visitor)角色:聲明了一個或者多個訪問操作快压,形成所有的具體元素角色必須實現的接口圆仔。
具體訪問者(ConcreteVisitor)角色:實現抽象訪問者角色所聲明的接口,也就是抽象訪問者所聲明的各個訪問操作蔫劣。
抽象節(jié)點(Element)角色:聲明一個接受操作坪郭,接受一個訪問者對象作為一個參量。
具體節(jié)點(ConcreteElement)角色:實現了抽象元素所規(guī)定的接受操作脉幢。
結構對象(ObiectStructure)角色:有如下的一些責任歪沃,可以遍歷結構中的所有元素嗦锐;如果需要,提供一個高層次的接口讓訪問者對象可以訪問每一個元素沪曙;如果需要奕污,可以設計成一個復合對象或者一個聚集,如列(List)或集合(Set)液走。?
解析器
意圖:
給定一個語言碳默,定義它的文法的一種表示,并定義一個解釋器缘眶,這個解釋器使用該表示來解釋語言中的句子.
適用性:
1嘱根、當有一個語言需要解釋執(zhí)行,并且你可以把該語言中的句子表示為一個抽象的語法樹時巷懈,可使用解釋器模式.而當存在以下情況時该抒,該模式的效果最好:
2、該文法簡單砸喻,對于復雜的文法柔逼,文法的類層次變得龐大而無法管理.此時,語法分析程序生成器這樣得工具時更好得選擇割岛。它們無需構建抽象語法樹即可解釋表達式,這樣可以節(jié)省空間而且還可以節(jié)省時間犯助;
3癣漆、效率不是一個關鍵的問題,最高效的解釋器通常不是通過直接解釋語法分析樹實現的剂买,而是首先把他們轉換成另外一種形式.例如:正則表達式通常被轉換成狀態(tài)機惠爽。但即使在這種情況下,轉換器仍可用解釋器模式實現瞬哼,該模式仍是有用的.
結構圖:
Interpreter設計模式中的幾種角色:
AbstractExpression:
-?聲明一個抽象的Interpret方法婚肆,抽象語法樹中所有的節(jié)點都必須實現該抽象方法。
TerminalExpression:
-?實現和語法中末端符號相關的Interpret方法坐慰。
-?在每個句子的末端符號中均需要一個TerminalExpression實例较性。
NonterminalExpression:
另外一個實現了AbstractExpression?接口的類,用來處理語法樹中非末端節(jié)點的語法结胀。它含有下一個AbstractExpression(s)的引用赞咙,調用它每個子節(jié)點的Interpret方法。
Context:
Interpreter方法所需要的信息的容器糟港,該信息對Interpreter而言全局可見攀操。充當幾個AbstractExpresssion?實例之間的通訊頻道。
PatternClient:
構建或者接收一個抽象語法書的實例秸抚。對于一個特定的句子而言速和,語法樹往往由若干個TerminalExpressions?和NonterminalExpression組成歹垫。PatterClient在合適的context下,調用Interpret方法颠放。
Interpreter模式的應用場合是interpreter模式應用中的難點排惨,只有滿足“業(yè)務規(guī)則頻繁變化,且類似的模式不斷重復出現慈迈,并且容易抽象為語法規(guī)則的問題”才適合使用Interpreter模式若贮。
使用Interpreter模式來表示文法規(guī)則,從而可以使用面向對象技巧來方便地“擴展”文法痒留。
Interpreter模式比較適合簡單的文法表示谴麦,對于復雜的文法表示,Interpreter模式會產生比較大的類層次結構伸头,這時候就不應該采用Interpreter模式了匾效。
效率不是一個Interpreter關心的關鍵問題。最高效的解釋器通常不是通過直接解釋語法分析樹實現的恤磷,而是首先將它們轉換成另一種形式面哼。例如:正則表達式通常被轉換成狀態(tài)機。但即使在這種情況下扫步,如果效率不是一個關鍵問題魔策,轉換器仍可用Interpreter模式實現,該模式仍是有用的河胎。