Design Pattern Quick Overview
?
?
?
Do we really need this design pattern? Just ignore, all the big guys requires it. For you, just understand the pattern and sleep over it.
?
心得:
1. 確實(shí)存在的dependency只能被轉(zhuǎn)移,不能被去除。 通過“轉(zhuǎn)移”來降低coupling(耦合度)。
2. Inversion of control和dependency injection概念接近(don't call me, I will call you)。dependency inversion則非常不同:instead of letting high-level component directly depends on low-level component, now the structure goes to be:
high-level component plus adapter Interface (it defines what are required from low-level needed for high-level)
low-level component plus adaptee class : adapter interface
In this way, it looks like that low-level now dpends on high-level so it seems to happen "dependency reversion". The key to make it work is: various patterns such as Plugin, Service Locator, or Dependency Injection are then employed to facilitate the run-time provisioning of the chosen low-level component implementation to the high-level component.
3.?Dependencies can be registered, bound, located, externally injected, etc., by many different means. Hence, moving dependency management from one module to another can be accomplished in a plenty of ways. However, there should exist a definite reason for moving a dependency away from the object that needs it because doing so can complicate the code hierarchy to such an extent that its usage appears to be "magical".?
?
關(guān)于design pattern的資料實(shí)在是太多太多了。這里只列出兩個(gè)我用到的:
1) 一句話總結(jié)各個(gè)pattern,coolshell上有一篇寫得挺好。
2) Javedoc DesignPattern
?
一個(gè)個(gè)來 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
1. Strategy(policy)
Take validate incoming data for example. there are many data types which require different validation methods. Here, if using strategy pattern, we will have a context object which can accept IStrategy (as interface or first-class function) and it's the master to actually execute the validation; and there are several strategy implementation classes (or functions). By passing different validation strategy into context class, different validation process can be executed.
?
2. Facade
Well, it's far easier than expected. By organizing client frequent logic into a facade class which is the bridge between client and the subsystem, client only depends on the facade class to make use of subsystem functionality. Below diagram tells so clearly:
?
3. Template method
Parent class controls the workflow of doing something, while each step can be overridden by sub classes in executing the workflow in parent class.?
?
?4. Adapter(wrapper)
Its intent is: without modifying plenty of places (modules) using a legacy class and still make the class work well in a new situation with more graceful interface,? in the new situation (calling place), use its adapter class (which treats the legacy class as its adaptee) instead of directly using the legacy class, while internally the adapter class just does some wrap work with the legacy class to provide a better interface for adapting to the new situation. For the new client, it uses the adapter class of course.
wiki's "(LegacyLine + LegacyRectangle) ++ (Line + Rectangle)" JAVA example illustrates the reality clearly.
?
5. Command (action, transaction)
個(gè)人覺得,這個(gè)模式的意義在于提出“command”的概念從而使得很多問題都可以通過加上這么非常通用的一層對(duì)象來解耦。command模式,理解下來,主要是兩點(diǎn):1)解耦invoker和receiver,使得他們可以完全被隔離。比如switch和light/engine,比如menuitem和document/application;2)支持undo。
?
兩個(gè)認(rèn)識(shí)(在理解command模式的過程中):1)兩個(gè)模塊之間有依賴關(guān)系(只要不是冗余的、可以去掉的), 這層關(guān)系是不能被去除的。只是看實(shí)現(xiàn)方法上是把兩個(gè)模塊緊耦合還是松散耦合在一起。design pattern做的事情就是:根據(jù)其適用的場(chǎng)合,通過對(duì)象間結(jié)構(gòu)或行為的改變來轉(zhuǎn)移“依賴”,使得耦合度大大降低。2)對(duì)于command模式而言,以switch為例。switch on/off和必須要引發(fā)的結(jié)果之間是必然的因果關(guān)系。最緊耦合的寫法是在switch對(duì)象的on/off函數(shù)里直接寫比如light on/off, 或者engine on/off;再進(jìn)一步的話,用個(gè)command類包裝出那部分邏輯,從而使得switch只依賴于command,從而把對(duì)具體操作對(duì)象的“依賴”轉(zhuǎn)移到了command類里;再進(jìn)一步,在command類的實(shí)現(xiàn)里,不要直接操作具體對(duì)象來on/off,而是通過fire event的方式在switch發(fā)送on/off event的時(shí)候觸發(fā)command的on/off來調(diào)用事先注冊(cè)好的各具體操作對(duì)象的delegate。這樣,最終,實(shí)現(xiàn)了一個(gè)非常松散耦合的結(jié)構(gòu)。A benefit of this particular implementation of the command pattern is that by making the switch not aware of the lamp/light, the switch can be used with any device, not just a light.
6. State
從結(jié)構(gòu)上,類似strategy模式:一個(gè)是通過切換狀態(tài)來改變對(duì)象行為,另一個(gè)是通過切換算法來改變對(duì)象行為。 這個(gè)模式的幾個(gè)關(guān)鍵點(diǎn):
1) 首先,要明白participants包括:context, state, concrete states以及client。client來調(diào)用context,并且state應(yīng)該對(duì)他是透明的,狀態(tài)的切換帶來的context對(duì)象行為的改變看上去是magic;context持有current state,并使用它來issue用戶的request,他一般不負(fù)責(zé)state的切換;各個(gè)具體的state對(duì)象,干實(shí)事的,GOF建議的是每一個(gè)state應(yīng)該知道它的next state從而把state switch的工作分?jǐn)偟矫恳粋€(gè)state里。
2)state的適用場(chǎng)合:一個(gè)是對(duì)象的行為依賴于其當(dāng)前狀態(tài),并且要求要在運(yùn)行時(shí)動(dòng)態(tài)的改變其行為;if-else深層次嵌套的場(chǎng)合。
?
7. Observer
C#的delegate/event處理機(jī)制和MFC的文檔和view的一致性處理機(jī)制(UpdateAllViews)都是observer的典型應(yīng)用。參與者是兩類:subject和observer;關(guān)系是:observer們對(duì)subject的改變感興趣,希望在subject做出改變的時(shí)候后被notify。做法非常直接:把observer本身注冊(cè)到subject里 (以IObserver或者delegate、函數(shù)指針的callback形式)。It is mainly used to implement distributed event handling systems.
8. Iterator
參與者有三:client,aggregate以及iterator;關(guān)系是:client想要遍歷aggregate的內(nèi)容(其內(nèi)部可能以各種數(shù)據(jù)結(jié)構(gòu)存儲(chǔ)數(shù)據(jù):hashtable,linkedlist,array,etc),又不想暴露aggregate的遍歷細(xì)節(jié)(因?yàn)橐蕾囉诖鎯?chǔ)數(shù)據(jù)的數(shù)據(jù)結(jié)構(gòu)或復(fù)雜性),就用iterator對(duì)象來封裝了對(duì)aggregate遍歷的細(xì)節(jié),只暴露友好的、抽象的first(),next()遍歷接口給client。
iterators are used to access the elements of an aggregate object sequentially without exposing its underlying implementation. An Iterator object encapsulates the internal structure of how the iteration occurs.?
9. Vistor
我對(duì)它總體上的理解:element.accept(visitor)和visitor.visit(concreteElement)是這個(gè)模式工作的關(guān)鍵。有些時(shí)候,直接對(duì)element繼承體系進(jìn)行修改(加virtual function)來實(shí)現(xiàn)對(duì)各個(gè)element的新的使用是不被允許的。這時(shí)候,創(chuàng)建visitor類+對(duì)element體系加入簡(jiǎn)單的accept virtual function就可以把新的訪問element的需求轉(zhuǎn)移到visitor類中,并可以簡(jiǎn)單的加入新的visitor類提供新的visit方法。
From wiki:
the visitor design pattern is a way of separating an algorithm from an object structure it operates on. A practical result of this separation is the ability to add new operations to existing object structures without modifying those structures.?
In essence, the visitor allows one to add new virtual functions to a family of classes without modifying the classes themselves; instead, one creates a visitor class that implements all of the appropriate specializations of the virtual function. The visitor takes the instance reference as input, and implements the goal through double dispatch.?
參與者有:element和visitor;
一般和composite pattern一起用;
double dispatch:實(shí)際調(diào)用visitor.visit的時(shí)候,這個(gè)function可以使用的是兩個(gè)具體對(duì)象:concreteVisitor和concreteElement。
(note about below diagram: Instead of creating "print" methods for each subclass (Wheel, Engine, Body, and Car), a single class (CarElementPrintVisitor) performs the required printing action.)
?
?http://en.wikipedia.org/wiki/Visitor_pattern
?http://www.javaworld.com/javaworld/javatips/jw-javatip98.html
10. Bridge
兩個(gè)關(guān)鍵點(diǎn)先:
1. It is meant to "decouple an abstraction from its implementation so that the two can vary independently".
2.?the bridge pattern is useful when both the class as well as what it does vary often. The class itself can be thought of as the implementation and what the class can do as the abstraction. The bridge pattern can also be thought of as two layers of abstraction.
Not well understand. Just in one case it would be applied widely: for a frequent referred + unstable class especially living on framework level of the app, we always use pImp / bridge pattern to avoid as many detail as possible exposed into header file (c++ only) to let this class's clients won't be bothered by frequent changes in it.
11. Chain of Responsibility
It is a design pattern consisting of a source of command objects and a series of processing objects. Each processing object contains a set of logic that describes the types of command objects that it can handle, and how to pass off those that it cannot handle to the next processing object in the chain. To be expanded, it can be tree of responsibility.Participants: to-be-processed objects (data), processing objects, client. The behavior is easy to understand and organize: firstly, client builds up the chain of processing objects by calling ProcessingObject::SetSuccessor(); secondly, wrap the to-be-processed object; pass it to the first processing object in the chain to kick off its processing. In normal design, all these tree roles are needed BUT intead of building up the chain to process, we always create a new function OR class to do below work:
void ProcessObject(Request request)
{
int flag = request.evalFlag();
if(flag < 100$)
{// go for processing objectA}
else if(flag < 1000$)
{// go for processing objectB}
else if(flag < 10000$)
{// go for processing objectC}
}
12. Composite
The key point for this pattern is: client intends to operate a collection of objects just the same as a single object. The solution is an interface that allows treating complex and primitive objects uniformly. The composite pattern describes that a group of objects are to be treated in the same way as a single instance of an object. The intent of a composite is to "compose" objects into tree structures to represent part-whole hierarchies. Implementing the composite pattern lets clients treat individual objects and compositions uniformly.
Participants: component, leaf : component, composite : component, client.
13. Flyweight
Participants: FlyweightFactory, Flyweight, client. This pattern behavior is: whenever client wants a flyweight object, he will make use of singleton flyweightFactory to get: flyweightFactory::get(), inside which: it will query its hashMap serving as a flyweight pool firstly; if found, just return the already created object; otherwise, create a new one and add it into the hashmap pool.?
14. Mediator
Participants: Concretemediator : Mediator, colleague, client. The pattern behavior is: client creates both mediator and colleague, and set mediator into colleague,and then colleague will do its works while inside it directly call mMediator.XX(). Some key points:
1.?Facade模式是解耦系統(tǒng)外到系統(tǒng)內(nèi)(單向)的對(duì)象關(guān)聯(lián)關(guān)系;Mediator模式是解耦系統(tǒng)內(nèi)各個(gè)對(duì)象之間(雙向)的關(guān)聯(lián)關(guān)系。
15. Memento
a class's state can be stored into another object whose ONLY responsibility is to store specific class's state.
Participants: Originator, Memento, client (careTaker). The pattern behavior is: client will new and use Originator to do his work; during the whole process, of course originator state will be changed; if client wants to save some states at any point, he can call originator.SaveToMemento() in which the state data will be stored into a new created memento object and returned. At last, when he wants a former state back, just call originator.RestoreFromMemento().
Key points:
1) Memento should be the container to cache orginator's state which can be either easy or complex data / info.
2) Originator should implement SaveToMemento() and RestoreFromMemento().
16. Proxy
一句話:為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。參與者:proxyObject,realObject,client.
1)A well-known example of the proxy pattern is a reference counting pointer object. 2)另一種情況是:某個(gè)客戶端不能直接操作到某個(gè)對(duì)象,但又必須和那個(gè)對(duì)象有所互動(dòng).舉例兩個(gè)具體情況:
(1)如果那個(gè)對(duì)象是一個(gè)是很大的圖片,需要花費(fèi)很長(zhǎng)時(shí)間才能顯示出來,那么當(dāng)這個(gè)圖片包含在文檔中時(shí),使用編輯器或?yàn)g覽器打開這個(gè)文檔,打開文檔必須很 迅速,不能等待大圖片處理完成,這時(shí)需要做個(gè)圖片Proxy來代替真正的圖片.
(2)如果那個(gè)對(duì)象在Internet的某個(gè)遠(yuǎn)端服務(wù)器上,直接操作這個(gè)對(duì)象因?yàn)榫W(wǎng)絡(luò)速度原因可能比較慢,那我們可以先用Proxy來代替那個(gè)對(duì)象.
總之原則是,對(duì)于開銷很大的對(duì)象,只有在使用它時(shí)才創(chuàng)建。
?
?
17. Decorator
The decorator pattern can be used to make it possible to extend (decorate) the functionality of a certain object at runtime, especially like below way to decorate a object:
有圖有真相:
?
18. Prototype
個(gè)人理解的幾點(diǎn):
0. 何謂prototype?這里指的是一個(gè)需要被相當(dāng)數(shù)量的copy的對(duì)象,那么這個(gè)對(duì)象一定程度上就變成了一個(gè)model,一個(gè)原型對(duì)象。提供一種方法可以方便高效的獲取它的一個(gè)copy是它的出現(xiàn)動(dòng)因。
1. 它的本質(zhì)在于解決某些場(chǎng)景下確實(shí)需要一個(gè)對(duì)象的true copy的問題。這種情況下,singleton不能滿足需求(因?yàn)槲覀円獙?duì)對(duì)象的一份copy操作而不是這個(gè)對(duì)象本身),“new”來全新創(chuàng)建一個(gè)對(duì)象不方便。
2. 它的實(shí)現(xiàn)其實(shí)非常直觀:只需要被copy的對(duì)象實(shí)現(xiàn)clone()方法。對(duì)于c#來說,已經(jīng)有protected memberwiseclone方法 + Icloneable接口來從語(yǔ)言本身支持了prototype模式。
3.?When creating an object is time consuming and a costly affair and you already have a most similar object instance in hand, then you go for prototype pattern.
19. Builder
The intention is to abstract steps of construction of objects so that different implementations of these steps can construct different representations of objects (將一個(gè)復(fù)雜的構(gòu)建與其表示相分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示).Participants: builder, concreteBuilder, Director, Product. Role and responsibilities:Builder:Abstract interface for creating objects (product).Concrete Builder: Provides implementation for Builder. It is an object able to construct other objects. Constructs and assembles parts to build the objects.Director: The Director class is responsible for managing the correct sequence of object creation. It receives a Concrete Builder as a parameter and executes the necessary operations on it.Product:The final object that will be created by the Director using Builder.??
Builder
20-22. Factory, Abstract Factory, Singleton
?先到這里,告一段落。
?
轉(zhuǎn)載于:https://www.cnblogs.com/taoxu0903/archive/2010/11/18/1880860.html
與50位技術(shù)專家面對(duì)面20年技術(shù)見證,附贈(zèng)技術(shù)全景圖總結(jié)
以上是生活随笔為你收集整理的Design Pattern Quick Overview的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 医院管理制度【第一辑】2010年11月1
- 下一篇: DB2基础学习一 DB2产品介绍