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. 確實存在的dependency只能被轉移,不能被去除。 通過“轉移”來降低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".?
?
關于design pattern的資料實在是太多太多了。這里只列出兩個我用到的:
1) 一句話總結各個pattern,coolshell上有一篇寫得挺好。
2) Javedoc DesignPattern
?
一個個來 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
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)
個人覺得,這個模式的意義在于提出“command”的概念從而使得很多問題都可以通過加上這么非常通用的一層對象來解耦。command模式,理解下來,主要是兩點:1)解耦invoker和receiver,使得他們可以完全被隔離。比如switch和light/engine,比如menuitem和document/application;2)支持undo。
?
兩個認識(在理解command模式的過程中):1)兩個模塊之間有依賴關系(只要不是冗余的、可以去掉的), 這層關系是不能被去除的。只是看實現方法上是把兩個模塊緊耦合還是松散耦合在一起。design pattern做的事情就是:根據其適用的場合,通過對象間結構或行為的改變來轉移“依賴”,使得耦合度大大降低。2)對于command模式而言,以switch為例。switch on/off和必須要引發的結果之間是必然的因果關系。最緊耦合的寫法是在switch對象的on/off函數里直接寫比如light on/off, 或者engine on/off;再進一步的話,用個command類包裝出那部分邏輯,從而使得switch只依賴于command,從而把對具體操作對象的“依賴”轉移到了command類里;再進一步,在command類的實現里,不要直接操作具體對象來on/off,而是通過fire event的方式在switch發送on/off event的時候觸發command的on/off來調用事先注冊好的各具體操作對象的delegate。這樣,最終,實現了一個非常松散耦合的結構。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
從結構上,類似strategy模式:一個是通過切換狀態來改變對象行為,另一個是通過切換算法來改變對象行為。 這個模式的幾個關鍵點:
1) 首先,要明白participants包括:context, state, concrete states以及client。client來調用context,并且state應該對他是透明的,狀態的切換帶來的context對象行為的改變看上去是magic;context持有current state,并使用它來issue用戶的request,他一般不負責state的切換;各個具體的state對象,干實事的,GOF建議的是每一個state應該知道它的next state從而把state switch的工作分攤到每一個state里。
2)state的適用場合:一個是對象的行為依賴于其當前狀態,并且要求要在運行時動態的改變其行為;if-else深層次嵌套的場合。
?
7. Observer
C#的delegate/event處理機制和MFC的文檔和view的一致性處理機制(UpdateAllViews)都是observer的典型應用。參與者是兩類:subject和observer;關系是:observer們對subject的改變感興趣,希望在subject做出改變的時候后被notify。做法非常直接:把observer本身注冊到subject里 (以IObserver或者delegate、函數指針的callback形式)。It is mainly used to implement distributed event handling systems.
8. Iterator
參與者有三:client,aggregate以及iterator;關系是:client想要遍歷aggregate的內容(其內部可能以各種數據結構存儲數據:hashtable,linkedlist,array,etc),又不想暴露aggregate的遍歷細節(因為依賴于存儲數據的數據結構或復雜性),就用iterator對象來封裝了對aggregate遍歷的細節,只暴露友好的、抽象的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
我對它總體上的理解:element.accept(visitor)和visitor.visit(concreteElement)是這個模式工作的關鍵。有些時候,直接對element繼承體系進行修改(加virtual function)來實現對各個element的新的使用是不被允許的。這時候,創建visitor類+對element體系加入簡單的accept virtual function就可以把新的訪問element的需求轉移到visitor類中,并可以簡單的加入新的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:實際調用visitor.visit的時候,這個function可以使用的是兩個具體對象: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
兩個關鍵點先:
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模式是解耦系統外到系統內(單向)的對象關聯關系;Mediator模式是解耦系統內各個對象之間(雙向)的關聯關系。
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
一句話:為其他對象提供一種代理以控制對這個對象的訪問。參與者:proxyObject,realObject,client.
1)A well-known example of the proxy pattern is a reference counting pointer object. 2)另一種情況是:某個客戶端不能直接操作到某個對象,但又必須和那個對象有所互動.舉例兩個具體情況:
(1)如果那個對象是一個是很大的圖片,需要花費很長時間才能顯示出來,那么當這個圖片包含在文檔中時,使用編輯器或瀏覽器打開這個文檔,打開文檔必須很 迅速,不能等待大圖片處理完成,這時需要做個圖片Proxy來代替真正的圖片.
(2)如果那個對象在Internet的某個遠端服務器上,直接操作這個對象因為網絡速度原因可能比較慢,那我們可以先用Proxy來代替那個對象.
總之原則是,對于開銷很大的對象,只有在使用它時才創建。
?
?
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
個人理解的幾點:
0. 何謂prototype?這里指的是一個需要被相當數量的copy的對象,那么這個對象一定程度上就變成了一個model,一個原型對象。提供一種方法可以方便高效的獲取它的一個copy是它的出現動因。
1. 它的本質在于解決某些場景下確實需要一個對象的true copy的問題。這種情況下,singleton不能滿足需求(因為我們要對對象的一份copy操作而不是這個對象本身),“new”來全新創建一個對象不方便。
2. 它的實現其實非常直觀:只需要被copy的對象實現clone()方法。對于c#來說,已經有protected memberwiseclone方法 + Icloneable接口來從語言本身支持了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 (將一個復雜的構建與其表示相分離,使得同樣的構建過程可以創建不同的表示).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
?先到這里,告一段落。
?
轉載于:https://www.cnblogs.com/taoxu0903/archive/2010/11/18/1880860.html
與50位技術專家面對面20年技術見證,附贈技術全景圖總結
以上是生活随笔為你收集整理的Design Pattern Quick Overview的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 医院管理制度【第一辑】2010年11月1
- 下一篇: DB2基础学习一 DB2产品介绍