設計模式及Python實現

本文源碼寄方於github:https://github.com/w392807287/Design_pattern_of_pythonnode

參考文獻:python

《大話設計模式》——吳強git

《Python設計模式》——pythontip.comgithub

《23種設計模式》——http://www.cnblogs.com/beijiguangyong/正則表達式

設計模式是什麼?

設計模式是通過總結、優化的,對咱們常常會碰到的一些編程問題的可重用解決方案。一個設計模式並不像一個類或一個庫那樣可以直接做用於咱們的代碼。反之,設計模式更爲高級,它是一種必須在特定情形下實現的一種方法模板。設計模式不會綁定具體的編程語言。一個好的設計模式應該可以用大部分編程語言實現(若是作不到所有的話,具體取決於語言特性)。最爲重要的是,設計模式也是一把雙刃劍,若是設計模式被用在不恰當的情形下將會形成災難,進而帶來無窮的麻煩。然而若是設計模式在正確的時間被用在正確地地方,它將是你的救星。算法

起初,你會認爲「模式」就是爲了解決一類特定問題而特別想出來的明智之舉。說的沒錯,看起來的確是經過不少人一塊兒工做,從不一樣的角度看待問題進而造成的一個最通用、最靈活的解決方案。也許這些問題你曾經見過或是曾經解決過,可是你的解決方案極可能沒有模式這麼完備。編程

雖然被稱爲「設計模式」,可是它們同「設計「領域並不是緊密聯繫。設計模式同傳統意義上的分析、設計與實現不一樣,事實上設計模式將一個完整的理念根植於程序中,因此它可能出如今分析階段或是更高層的設計階段。頗有趣的是由於設計模式的具體體現是程序代碼,所以可能會讓你認爲它不會在具體實現階段以前出現(事實上在進入具體實現階段以前你都沒有意識到正在使用具體的設計模式)。設計模式

能夠經過程序設計的基本概念來理解模式:增長一個抽象層。抽象一個事物就是隔離任何具體細節,這麼作的目的是爲了將那些不變的核心部分從其餘細節中分離出來。當你發現你程序中的某些部分常常由於某些緣由改動,而你不想讓這些改動的部分引起其餘部分的改動,這時候你就須要思考那些不會變更的設計方法了。這麼作不只會使代碼可維護性更高,並且會讓代碼更易於理解,從而下降開發成本。api

這裏列舉了三種最基本的設計模式:數據結構

  1. 建立模式,提供實例化的方法,爲適合的情況提供相應的對象建立方法。
  2. 結構化模式,一般用來處理實體之間的關係,使得這些實體可以更好地協同工做。
  3. 行爲模式,用於在不一樣的實體建進行通訊,爲實體之間的通訊提供更容易,更靈活的通訊方法。

建立型

1. Factory Method(工廠方法)

2. Abstract Factory(抽象工廠)

3. Builder(建造者)

4. Prototype(原型)

5. Singleton(單例)

結構型

6. Adapter Class/Object(適配器)

7. Bridge(橋接)

8. Composite(組合)

9. Decorator(裝飾)

10. Facade(外觀)

11. Flyweight(享元)

12. Proxy(代理)

行爲型

13. Interpreter(解釋器)

14. Template Method(模板方法)

15. Chain of Responsibility(責任鏈)

16. Command(命令)

17. Iterator(迭代器)

18. Mediator(中介者)

19. Memento(備忘錄)

20. Observer(觀察者)

21. State(狀態)

22. Strategy(策略)

23. Visitor(訪問者)

建立型

1.Factory Method(工廠方法)

意圖:

定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method 使個類的實例化延遲到其子類。

適用性:

當一個類不知道它所必須建立的對象的類的時候。

當一個類但願由它的子類來指定它所建立的對象的時候。

當類將建立對象的職責委託給多個幫助子類中的某一個,而且你但願將哪個幫助子類是代理者這一信息局部化的時候。

實現:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/python
#coding:utf8
'''
Factory Method
'''
 
class  ChinaGetter:
     """A simple localizer a la gettext"""
     def  __init__( self ):
         self .trans  =  dict (dog = u "小狗" , cat = u "小貓" )
 
     def  get( self , msgid):
         """We'll punt if we don't have a translation"""
         try :
             return  self .trans[msgid]
         except  KeyError:
             return  str (msgid)
 
 
class  EnglishGetter:
     """Simply echoes the msg ids"""
     def  get( self , msgid):
         return  str (msgid)
 
 
def  get_localizer(language = "English" ):
     """The factory method"""
     languages  =  dict (English = EnglishGetter, China = ChinaGetter)
     return  languages[language]()
 
# Create our localizers
e, g  =  get_localizer( "English" ), get_localizer( "China" )
# Localize some text
for  msgid  in  "dog parrot cat bear" .split():
     print (e.get(msgid), g.get(msgid))

  

2. Abstract Factory(抽象工廠)

意圖:

 

提供一個建立一系列相關或相互依賴對象的接口,而無需指定它們具體的類。 
適用性:

 一個系統要獨立於它的產品的建立、組合和表示時。

 一個系統要由多個產品系列中的一個來配置時。

 當你要強調一系列相關的產品對象的設計以便進行聯合使用時。

 當你提供一個產品類庫,而只想顯示它們的接口而不是實現時。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/python
#coding:utf8
'''
Abstract Factory
'''
 
import  random
 
class  PetShop:
     """A pet shop"""
 
     def  __init__( self , animal_factory = None ):
         """pet_factory is our abstract factory.
         We can set it at will."""
 
         self .pet_factory  =  animal_factory
 
     def  show_pet( self ):
         """Creates and shows a pet using the
         abstract factory"""
 
         pet  =  self .pet_factory.get_pet()
         print ( "This is a lovely" str (pet))
         print ( "It says" , pet.speak())
         print ( "It eats" self .pet_factory.get_food())
 
 
# Stuff that our factory makes
 
class  Dog:
     def  speak( self ):
         return  "woof"
 
     def  __str__( self ):
         return  "Dog"
 
 
class  Cat:
     def  speak( self ):
         return  "meow"
 
     def  __str__( self ):
         return  "Cat"
 
 
# Factory classes
 
class  DogFactory:
     def  get_pet( self ):
         return  Dog()
 
     def  get_food( self ):
         return  "dog food"
 
 
class  CatFactory:
     def  get_pet( self ):
         return  Cat()
 
     def  get_food( self ):
         return  "cat food"
 
 
# Create the proper family
def  get_factory():
     """Let's be dynamic!"""
     return  random.choice([DogFactory, CatFactory])()
 
 
# Show pets with various factories
if  __name__  = =  "__main__" :
     shop  =  PetShop()
     for  in  range ( 3 ):
         shop.pet_factory  =  get_factory()
         shop.show_pet()
         print ( "="  *  20 )

  

3. Builder(建造者)

意圖:

將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立不一樣的表示。

適用性:

當建立複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。

當構造過程必須容許被構造的對象有不一樣的表示時。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
#!/usr/bin/python
#coding:utf8
 
"""
     Builder
"""
 
# Director
class  Director( object ):
     def  __init__( self ):
         self .builder  =  None
 
     def  construct_building( self ):
         self .builder.new_building()
         self .builder.build_floor()
         self .builder.build_size()
 
     def  get_building( self ):
         return  self .builder.building
 
 
# Abstract Builder
class  Builder( object ):
     def  __init__( self ):
         self .building  =  None
 
     def  new_building( self ):
         self .building  =  Building()
 
 
# Concrete Builder
class  BuilderHouse(Builder):
     def  build_floor( self ):
         self .building.floor  =  'One'
 
     def  build_size( self ):
         self .building.size  =  'Big'
 
 
class  BuilderFlat(Builder):
     def  build_floor( self ):
         self .building.floor  =  'More than One'
 
     def  build_size( self ):
         self .building.size  =  'Small'
 
 
# Product
class  Building( object ):
     def  __init__( self ):
         self .floor  =  None
         self .size  =  None
 
     def  __repr__( self ):
         return  'Floor: %s | Size: %s'  %  ( self .floor,  self .size)
 
 
# Client
if  __name__  = =  "__main__" :
     director  =  Director()
     director.builder  =  BuilderHouse()
     director.construct_building()
     building  =  director.get_building()
     print (building)
     director.builder  =  BuilderFlat()
     director.construct_building()
     building  =  director.get_building()
     print (building)

  

4. Prototype(原型)

意圖:

用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。

適用性:

當要實例化的類是在運行時刻指定時,例如,經過動態裝載;或者爲了不建立一個與產品類層次平行的工廠類層次時;或者當一個類的實例只能有幾個不一樣狀態組合中的一種時。創建相應數目的原型並克隆它們可能比每次用合適的狀態手工實例化該類更方便一些。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#!/usr/bin/python
#coding:utf8
'''
Prototype
'''
 
import  copy
 
class  Prototype:
     def  __init__( self ):
         self ._objects  =  {}
 
     def  register_object( self , name, obj):
         """Register an object"""
         self ._objects[name]  =  obj
 
     def  unregister_object( self , name):
         """Unregister an object"""
         del  self ._objects[name]
 
     def  clone( self , name,  * * attr):
         """Clone a registered object and update inner attributes dictionary"""
         obj  =  copy.deepcopy( self ._objects.get(name))
         obj.__dict__.update(attr)
         return  obj
 
 
def  main():
     class  A:
         def  __str__( self ):
             return  "I am A"
 
     =  A()
     prototype  =  Prototype()
     prototype.register_object( 'a' , a)
     =  prototype.clone( 'a' , a = 1 , b = 2 , c = 3 )
 
     print (a)
     print (b.a, b.b, b.c)
 
 
if  __name__  = =  '__main__' :
     main()

  

5. Singleton(單例)

意圖:

保證一個類僅有一個實例,並提供一個訪問它的全局訪問點。

適用性:

當類只能有一個實例並且客戶能夠從一個衆所周知的訪問點訪問它時。

當這個惟一實例應該是經過子類化可擴展的,而且客戶應該無需更改代碼就能使用一個擴展的實例時。

 

實現:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/usr/bin/python
#coding:utf8
'''
Singleton
'''
 
class  Singleton( object ):
     ''''' A python style singleton '''
 
     def  __new__( cls * args,  * * kw):
         if  not  hasattr ( cls '_instance' ):
             org  =  super (Singleton,  cls )
             cls ._instance  =  org.__new__( cls * args,  * * kw)
         return  cls ._instance
 
 
if  __name__  = =  '__main__' :
     class  SingleSpam(Singleton):
         def  __init__( self , s):
             self .s  =  s
 
         def  __str__( self ):
             return  self .s
 
 
     s1  =  SingleSpam( 'spam' )
     print  id (s1), s1
     s2  =  SingleSpam( 'spa' )
     print  id (s2), s2
     print  id (s1), s1

  

結構型

6. Adapter Class/Object(適配器)

意圖:

 將一個類的接口轉換成客戶但願的另一個接口。Adapter 模式使得本來因爲接口不兼容而不能一塊兒工做的那些類能夠一塊兒工做。 

適用性:

 你想使用一個已經存在的類,而它的接口不符合你的需求。

你想建立一個能夠複用的類,該類能夠與其餘不相關的類或不可預見的類(即那些接口可能不必定兼容的類)協同工做。

(僅適用於對象Adapter )你想使用一些已經存在的子類,可是不可能對每個都進行子類化以匹配它們的接口。對象適配器能夠適配它的父類接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#!/usr/bin/python
#coding:utf8
'''
Adapter
'''
 
import  os
 
 
class  Dog( object ):
     def  __init__( self ):
         self .name  =  "Dog"
 
     def  bark( self ):
         return  "woof!"
 
 
class  Cat( object ):
     def  __init__( self ):
         self .name  =  "Cat"
 
     def  meow( self ):
         return  "meow!"
 
 
class  Human( object ):
     def  __init__( self ):
         self .name  =  "Human"
 
     def  speak( self ):
         return  "'hello'"
 
 
class  Car( object ):
     def  __init__( self ):
         self .name  =  "Car"
 
     def  make_noise( self , octane_level):
         return  "vroom%s"  %  ( "!"  *  octane_level)
 
 
class  Adapter( object ):
     """
     Adapts an object by replacing methods.
     Usage:
     dog = Dog
     dog = Adapter(dog, dict(make_noise=dog.bark))
     """
     def  __init__( self , obj, adapted_methods):
         """We set the adapted methods in the object's dict"""
         self .obj  =  obj
         self .__dict__.update(adapted_methods)
 
     def  __getattr__( self , attr):
         """All non-adapted calls are passed to the object"""
         return  getattr ( self .obj, attr)
 
 
def  main():
     objects  =  []
     dog  =  Dog()
     objects.append(Adapter(dog,  dict (make_noise = dog.bark)))
     cat  =  Cat()
     objects.append(Adapter(cat,  dict (make_noise = cat.meow)))
     human  =  Human()
     objects.append(Adapter(human,  dict (make_noise = human.speak)))
     car  =  Car()
     car_noise  =  lambda : car.make_noise( 3 )
     objects.append(Adapter(car,  dict (make_noise = car_noise)))
 
     for  obj  in  objects:
         print  "A" , obj.name,  "goes" , obj.make_noise()
 
 
if  __name__  = =  "__main__" :
     main()

  

7. Bridge(橋接)

意圖:

 將抽象部分與它的實現部分分離,使它們均可以獨立地變化。

 適用性:

 你不但願在抽象和它的實現部分之間有一個固定的綁定關係。例如這種狀況多是由於,在程序運行時刻實現部分應能夠被選擇或者切換。

 類的抽象以及它的實現都應該能夠經過生成子類的方法加以擴充。這時Bridge 模式使你能夠對不一樣的抽象接口和實現部分進行組合,並分別對它們進行擴充。

 對一個抽象的實現部分的修改應對客戶不產生影響,即客戶的代碼沒必要從新編譯。

 (C++)你想對客戶徹底隱藏抽象的實現部分。在C++中,類的表示在類接口中是可見的。

 有許多類要生成。這樣一種類層次結構說明你必須將一個對象分解成兩個部分。Rumbaugh 稱這種類層次結構爲「嵌套的普化」(nested generalizations )。

 你想在多個對象間共享實現(可能使用引用計數),但同時要求客戶並不知道這一點。一個簡單的例子即是Coplien 的String 類[ Cop92 ],在這個類中多個對象能夠共享同一個字符串表示(StringRep)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
#!/usr/bin/python
#coding:utf8
'''
Bridge
'''
 
 
# ConcreteImplementor 1/2
class  DrawingAPI1( object ):
     def  draw_circle( self , x, y, radius):
         print ( 'API1.circle at {}:{} radius {}' . format (x, y, radius))
 
 
# ConcreteImplementor 2/2
class  DrawingAPI2( object ):
     def  draw_circle( self , x, y, radius):
         print ( 'API2.circle at {}:{} radius {}' . format (x, y, radius))
 
 
# Refined Abstraction
class  CircleShape( object ):
     def  __init__( self , x, y, radius, drawing_api):
         self ._x  =  x
         self ._y  =  y
         self ._radius  =  radius
         self ._drawing_api  =  drawing_api
 
     # low-level i.e. Implementation specific
     def  draw( self ):
         self ._drawing_api.draw_circle( self ._x,  self ._y,  self ._radius)
 
     # high-level i.e. Abstraction specific
     def  scale( self , pct):
         self ._radius  * =  pct
 
 
def  main():
     shapes  =  (
         CircleShape( 1 2 3 , DrawingAPI1()),
         CircleShape( 5 7 11 , DrawingAPI2())
     )
 
     for  shape  in  shapes:
         shape.scale( 2.5 )
         shape.draw()
 
 
if  __name__  = =  '__main__' :
     main()

  

8. Composite(組合)

意圖:

 將對象組合成樹形結構以表示「部分-總體」的層次結構。C o m p o s i t e 使得用戶對單個對象和組合對象的使用具備一致性。 

適用性:

 你想表示對象的部分-總體層次結構。

你但願用戶忽略組合對象與單個對象的不一樣,用戶將統一地使用組合結構中的全部對象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#!/usr/bin/python
#coding:utf8
 
"""
Composite
"""
 
class  Component:
     def  __init__( self ,strName):
         self .m_strName  =  strName
     def  Add( self ,com):
         pass
     def  Display( self ,nDepth):
         pass
 
class  Leaf(Component):
     def  Add( self ,com):
         print  "leaf can't add"
     def  Display( self ,nDepth):
         strtemp  =  "-"  *  nDepth
         strtemp = strtemp + self .m_strName
         print  strtemp
 
class  Composite(Component):
     def  __init__( self ,strName):
         self .m_strName  =  strName
         self .c  =  []
     def  Add( self ,com):
         self .c.append(com)
     def  Display( self ,nDepth):
         strtemp  =  "-" * nDepth
         strtemp = strtemp + self .m_strName
         print  strtemp
         for  com  in  self .c:
             com.Display(nDepth + 2 )
 
if  __name__  = =  "__main__" :
     =  Composite( "Wong" )
     p.Add(Leaf( "Lee" ))
     p.Add(Leaf( "Zhao" ))
     p1  =  Composite( "Wu" )
     p1.Add(Leaf( "San" ))
     p.Add(p1)
     p.Display( 1 );

  

9. Decorator(裝飾)

意圖: 
動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator 模式相比生成子類更爲靈活。 
適用性:

 在不影響其餘對象的狀況下,以動態、透明的方式給單個對象添加職責。

 處理那些能夠撤消的職責。

當不能採用生成子類的方法進行擴充時。一種狀況是,可能有大量獨立的擴展,爲支持每一種組合將產生大量的子類,使得子類數目呈爆炸性增加。另外一種狀況多是由於類定義被隱藏,或類定義不能用於生成子類。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#!/usr/bin/python
#coding:utf8
'''
Decorator
'''
 
class  foo( object ):
     def  f1( self ):
         print ( "original f1" )
 
     def  f2( self ):
         print ( "original f2" )
 
 
class  foo_decorator( object ):
     def  __init__( self , decoratee):
         self ._decoratee  =  decoratee
 
     def  f1( self ):
         print ( "decorated f1" )
         self ._decoratee.f1()
 
     def  __getattr__( self , name):
         return  getattr ( self ._decoratee, name)
 
=  foo()
=  foo_decorator(u)
v.f1()
v.f2()

  

10. Facade(外觀)

意圖:

 爲子系統中的一組接口提供一個一致的界面,Facade模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。

適用性:

當你要爲一個複雜子系統提供一個簡單接口時。子系統每每由於不斷演化而變得愈來愈複雜。大多數模式使用時都會產生更多更小的類。這使得子系統更具可重用性,也更容易對子系統進行定製,但這也給那些不須要定製子系統的用戶帶來一些使用上的困難。Facade 能夠提供一個簡單的缺省視圖,這一視圖對大多數用戶來講已經足夠,而那些須要更多的可定製性的用戶能夠越過facade層。

客戶程序與抽象類的實現部分之間存在着很大的依賴性。引入facade 將這個子系統與客戶以及其餘的子系統分離,能夠提升子系統的獨立性和可移植性。

當你須要構建一個層次結構的子系統時,使用facade模式定義子系統中每層的入口點。若是子系統之間是相互依賴的,你可讓它們僅經過facade進行通信,從而簡化了它們之間的依賴關係。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#!/usr/bin/python
#coding:utf8
'''
Decorator
'''
import  time
 
SLEEP  =  0.5
 
# Complex Parts
class  TC1:
     def  run( self ):
         print ( "###### In Test 1 ######" )
         time.sleep(SLEEP)
         print ( "Setting up" )
         time.sleep(SLEEP)
         print ( "Running test" )
         time.sleep(SLEEP)
         print ( "Tearing down" )
         time.sleep(SLEEP)
         print ( "Test Finished\n" )
 
 
class  TC2:
     def  run( self ):
         print ( "###### In Test 2 ######" )
         time.sleep(SLEEP)
         print ( "Setting up" )
         time.sleep(SLEEP)
         print ( "Running test" )
         time.sleep(SLEEP)
         print ( "Tearing down" )
         time.sleep(SLEEP)
         print ( "Test Finished\n" )
 
 
class  TC3:
     def  run( self ):
         print ( "###### In Test 3 ######" )
         time.sleep(SLEEP)
         print ( "Setting up" )
         time.sleep(SLEEP)
         print ( "Running test" )
         time.sleep(SLEEP)
         print ( "Tearing down" )
         time.sleep(SLEEP)
         print ( "Test Finished\n" )
 
 
# Facade
class  TestRunner:
     def  __init__( self ):
         self .tc1  =  TC1()
         self .tc2  =  TC2()
         self .tc3  =  TC3()
         self .tests  =  [i  for  in  ( self .tc1,  self .tc2,  self .tc3)]
 
     def  runAll( self ):
         [i.run()  for  in  self .tests]
 
 
# Client
if  __name__  = =  '__main__' :
     testrunner  =  TestRunner()
     testrunner.runAll()

  

11. Flyweight(享元)

意圖:

運用共享技術有效地支持大量細粒度的對象。

適用性:

一個應用程序使用了大量的對象。

徹底因爲使用大量的對象,形成很大的存儲開銷。

對象的大多數狀態均可變爲外部狀態。

若是刪除對象的外部狀態,那麼能夠用相對較少的共享對象取代不少組對象。 

應用程序不依賴於對象標識。因爲Flyweight 對象能夠被共享,對於概念上明顯有別的對象,標識測試將返回真值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/python
#coding:utf8
'''
Flyweight
'''
 
import  weakref 
 
 
class  Card( object ):
     """The object pool. Has builtin reference counting"""
     _CardPool  =  weakref.WeakValueDictionary()
 
     """Flyweight implementation. If the object exists in the
     pool just return it (instead of creating a new one)"""
     def  __new__( cls , value, suit):        
         obj  =  Card._CardPool.get(value  +  suit,  None )        
         if  not  obj:            
             obj  =  object .__new__( cls )            
             Card._CardPool[value  +  suit]  =  obj            
             obj.value, obj.suit  =  value, suit         
         return  obj
 
     # def __init__(self, value, suit):        
     #     self.value, self.suit = value, suit     
 
     def  __repr__( self ):        
         return  "<Card: %s%s>"  %  ( self .value,  self .suit)     
 
 
if  __name__  = =  '__main__' :
     # comment __new__ and uncomment __init__ to see the difference
     c1  =  Card( '9' 'h' )
     c2  =  Card( '9' 'h' )
     print (c1, c2)
     print (c1  = =  c2)
     print ( id (c1),  id (c2))

  

12. Proxy(代理)

意圖:

 

爲其餘對象提供一種代理以控制對這個對象的訪問。

 

適用性:

 在須要用比較通用和複雜的對象指針代替簡單的指針的時候,使用Proxy模式。下面是一 些可使用Proxy 模式常見狀況: 

1) 遠程代理(Remote Proxy )爲一個對象在不一樣的地址空間提供局部表明。 NEXTSTEP[Add94] 使用NXProxy 類實現了這一目的。Coplien[Cop92] 稱這種代理爲「大使」 (Ambassador )。 
2 )虛代理(Virtual Proxy )根據須要建立開銷很大的對象。在動機一節描述的ImageProxy 就是這樣一種代理的例子。 
3) 保護代理(Protection Proxy )控制對原始對象的訪問。保護代理用於對象應該有不一樣 的訪問權限的時候。例如,在Choices 操做系統[ CIRM93]中KemelProxies爲操做系統對象提供 了訪問保護。 
4 )智能指引(Smart Reference )取代了簡單的指針,它在訪問對象時執行一些附加操做。 它的典型用途包括:對指向實際對象的引用計數,這樣當該對象沒有引用時,能夠自動釋放它(也稱爲SmartPointers[Ede92 ] )。

 當第一次引用一個持久對象時,將它裝入內存。

 在訪問一個實際對象前,檢查是否已經鎖定了它,以確保其餘對象不能改變它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
#!/usr/bin/python
#coding:utf8
'''
Proxy
'''
 
import  time
 
class  SalesManager:
     def  work( self ):
         print ( "Sales Manager working..." )
 
     def  talk( self ):
         print ( "Sales Manager ready to talk" )
 
class  Proxy:
     def  __init__( self ):
         self .busy  =  'No'
         self .sales  =  None
 
     def  work( self ):
         print ( "Proxy checking for Sales Manager availability" )
         if  self .busy  = =  'No' :
             self .sales  =  SalesManager()
             time.sleep( 2 )
             self .sales.talk()
         else :
             time.sleep( 2 )
             print ( "Sales Manager is busy" )
 
 
if  __name__  = =  '__main__' :
     =  Proxy()
     p.work()
     p.busy  =  'Yes'
     p.work()

  

行爲型

13. Interpreter(解釋器)

意圖:

給定一個語言,定義它的文法的一種表示,並定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。

適用性:

當有一個語言須要解釋執行, 而且你可將該語言中的句子表示爲一個抽象語法樹時,可以使用解釋器模式。而當存在如下狀況時該模式效果最好:

該文法簡單對於複雜的文法, 文法的類層次變得龐大而沒法管理。此時語法分析程序生成器這樣的工具是更好的選擇。它們無需構建抽象語法樹便可解釋表達式, 這樣能夠節省空間並且還可能節省時間。

效率不是一個關鍵問題最高效的解釋器一般不是經過直接解釋語法分析樹實現的, 而是首先將它們轉換成另外一種形式。例如,正則表達式一般被轉換成狀態機。但即便在這種狀況下, 轉換器仍可用解釋器模式實現, 該模式還是有用的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#!/usr/bin/python
#coding:utf8
'''
Interpreter
'''
 
class  Context:
     def  __init__( self ):
         self . input = ""
         self .output = ""
 
class  AbstractExpression:
     def  Interpret( self ,context):
         pass
 
class  Expression(AbstractExpression):
     def  Interpret( self ,context):
         print  "terminal interpret"
 
class  NonterminalExpression(AbstractExpression):
     def  Interpret( self ,context):
         print  "Nonterminal interpret"
 
if  __name__  = =  "__main__" :
     context =  ""
     =  []
     =  +  [Expression()]
     =  +  [NonterminalExpression()]
     =  +  [Expression()]
     =  +  [Expression()]
     for  in  c:
         a.Interpret(context)

  

14. Template Method(模板方法)

意圖:

定義一個操做中的算法的骨架,而將一些步驟延遲到子類中。TemplateMethod 使得子類能夠不改變一個算法的結構便可重定義該算法的某些特定步驟。

適用性:

一次性實現一個算法的不變的部分,並將可變的行爲留給子類來實現。

各子類中公共的行爲應被提取出來並集中到一個公共父類中以免代碼重複。這是Opdyke 和Johnson所描述過的「重分解以通常化」的一個很好的例子[ OJ93 ]。首先識別現有代碼中的不一樣之處,而且將不一樣之處分離爲新的操做。最後,用一個調用這些新的操做的模板方法來替換這些不一樣的代碼。

控制子類擴展。模板方法只在特定點調用「hook 」操做(參見效果一節),這樣就只容許在這些點進行擴展。

相關文章
相關標籤/搜索