设计模式及Python实现

2019年12月10日 阅读数:242
这篇文章主要向大家介绍设计模式及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 ”操做(参见效果一节),这样就只容许在这些点进行扩展。