二十三种设计模式及其python实现

本文为博客转载:https://www.cnblogs.com/Liqiongyu/p/5916710.html

设计模式是什么?

创建型

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(访问者)


本文源码寄方于github:https://github.com/w392807287/Design_pattern_of_python

参考文献:

《大话设计模式》——吴强

《Python设计模式》——pythontip.com

《23种设计模式》——http://www.cnblogs.com/beijiguangyong/

设计模式是什么?

设计模式是经过总结、优化的,对我们经常会碰到的一些编程问题的可重用解决方案。一个设计模式并不像一个类或一个库那样能够直接作用于我们的代码。反之,设计模式更为高级,它是一种必须在特定情形下实现的一种方法模板。设计模式不会绑定具体的编程语言。一个好的设计模式应该能够用大部分编程语言实现(如果做不到全部的话,具体取决于语言特性)。最为重要的是,设计模式也是一把双刃剑,如果设计模式被用在不恰当的情形下将会造成灾难,进而带来无穷的麻烦。然而如果设计模式在正确的时间被用在正确地地方,它将是你的救星。

起初,你会认为“模式”就是为了解决一类特定问题而特别想出来的明智之举。说的没错,看起来的确是通过很多人一起工作,从不同的角度看待问题进而形成的一个最通用、最灵活的解决方案。也许这些问题你曾经见过或是曾经解决过,但是你的解决方案很可能没有模式这么完备。

虽然被称为“设计模式”,但是它们同“设计“领域并非紧密联系。设计模式同传统意义上的分析、设计与实现不同,事实上设计模式将一个完整的理念根植于程序中,所以它可能出现在分析阶段或是更高层的设计阶段。很有趣的是因为设计模式的具体体现是程序代码,因此可能会让你认为它不会在具体实现阶段之前出现(事实上在进入具体实现阶段之前你都没有意识到正在使用具体的设计模式)。

可以通过程序设计的基本概念来理解模式:增加一个抽象层。抽象一个事物就是隔离任何具体细节,这么做的目的是为了将那些不变的核心部分从其他细节中分离出来。当你发现你程序中的某些部分经常因为某些原因改动,而你不想让这些改动的部分引发其他部分的改动,这时候你就需要思考那些不会变动的设计方法了。这么做不仅会使代码可维护性更高,而且会让代码更易于理解,从而降低开发成本。

这里列举了三种最基本的设计模式:

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

 

2. Abstract Factory(抽象工厂

意图:

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。 
适用性:

 一个系统要独立于它的产品的创建、组合和表示时。

 一个系统要由多个产品系列中的一个来配置时。

 当你要强调一系列相关的产品对象的设计以便进行联合使用时。

 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

实现:


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

 

3. Builder(建造者)

意图:

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用性:

当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。

当构造过程必须允许被构造的对象有不同的表示时。

实现:


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

 

4. Prototype(原型)

意图:

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

适用性:

当要实例化的类是在运行时刻指定时,例如,通过动态装载;或者为了避免创建一个与产品类层次平行的工厂类层次时;或者当一个类的实例只能有几个不同状态组合中的一种时。建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。

实现:


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

 

5. Singleton(单例)

意图:

保证一个类仅有一个实例,并提供一个访问它的全局访问点。

适用性:

当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。

当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。

 

实现:


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

 

结构型

6. Adapter Class/Object(适配器)

意图:

 将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。 

适用性:

 你想使用一个已经存在的类,而它的接口不符合你的需求。

你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。

(仅适用于对象Adapter )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

实现:


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


7. Bridge(桥接)

意图:

 将抽象部分与它的实现部分分离,使它们都可以独立地变化。

 适用性

 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,在程序运行时刻实现部分应可以被选择或者切换。

 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时Bridge 模式使你可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。

 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。

 (C++)你想对客户完全隐藏抽象的实现部分。在C++中,类的表示在类接口中是可见的。

 有许多类要生成。这样一种类层次结构说明你必须将一个对象分解成两个部分。Rumbaugh 称这种类层次结构为“嵌套的普化”(nested generalizations )。

 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。一个简单的例子便是Coplien 的String 类[ Cop92 ],在这个类中多个对象可以共享同一个字符串表示(StringRep)。

实现:


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


8. Composite(组合)  

意图:

 将对象组合成树形结构以表示“部分-整体”的层次结构。C o m p o s i t e 使得用户对单个对象和组合对象的使用具有一致性。 

适用性:

 你想表示对象的部分-整体层次结构。

你希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

实现:


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


9. Decorator(装饰)  

意图: 
动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator 模式相比生成子类更为灵活。 
适用性:

在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

 处理那些可以撤消的职责。

当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类。

实现:


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


10. Facade(外观)  

意图:

 为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。

适用性:

当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。

客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。

当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。

实现:


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


11. Flyweight(享元)  

意图:

运用共享技术有效地支持大量细粒度的对象。

适用性:

一个应用程序使用了大量的对象。

完全由于使用大量的对象,造成很大的存储开销。

对象的大多数状态都可变为外部状态。

如果删除对象的外部状态,那么可以用相对较少的共享对象取代很多组对象。 

应用程序不依赖于对象标识。由于Flyweight 对象可以被共享,对于概念上明显有别的对象,标识测试将返回真值。

实现:


   
   
  1. #!/usr/bin/python
  2. #coding:utf8
  3. '''
  4. Flyweight
  5. '''
  6. import weakref 
  7. class Card( object):
  8.      """The object pool. Has builtin reference counting"""
  9.     _CardPool = weakref.WeakValueDictionary()
  10.      """Flyweight implementation. If the object exists in the
  11.     pool just return it (instead of creating a new one)"""
  12.      def __new__( cls, value, suit):        
  13.         obj = Card._CardPool.get(value + suit, None)        
  14.          if not obj:            
  15.             obj = object.__new__(cls)            
  16.             Card._CardPool[value + suit] = obj            
  17.             obj.value, obj.suit = value, suit         
  18.          return obj
  19.      # def __init__(self, value, suit):        
  20.      #     self.value, self.suit = value, suit     
  21.      def __repr__( self):        
  22.          return "<Card: %s%s>" % (self.value, self.suit)     
  23. if __name__ == '__main__':
  24.      # comment __new__ and uncomment __init__ to see the difference
  25.     c1 = Card( '9', 'h')
  26.     c2 = Card( '9', 'h')
  27.      print(c1, c2)
  28.      print(c1 == c2)
  29.      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. #!/usr/bin/python
  2. #coding:utf8
  3. '''
  4. Proxy
  5. '''
  6. import time
  7. class SalesManager:
  8.      def work( self):
  9.          print( "Sales Manager working...")
  10.      def talk( self):
  11.          print( "Sales Manager ready to talk")
  12. class Proxy:
  13.      def __init__( self):
  14.         self.busy = 'No'
  15.         self.sales = None
  16.      def work( self):
  17.          print( "Proxy checking for Sales Manager availability")
  18.          if self.busy == 'No':
  19.             self.sales = SalesManager()
  20.             time.sleep( 2)
  21.             self.sales.talk()
  22.          else:
  23.             time.sleep( 2)
  24.              print( "Sales Manager is busy")
  25. if __name__ == '__main__':
  26.     p = Proxy()
  27.     p.work()
  28.     p.busy = 'Yes'
  29.     p.work()


行为型  

13. Interpreter(解释器)

意图:

给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

适用性:

当有一个语言需要解释执行, 并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式。而当存在以下情况时该模式效果最好:

该文法简单对于复杂的文法, 文法的类层次变得庞大而无法管理。此时语法分析程序生成器这样的工具是更好的选择。它们无需构建抽象语法树即可解释表达式, 这样可以节省空间而且还可能节省时间。

效率不是一个关键问题最高效的解释器通常不是通过直接解释语法分析树实现的, 而是首先将它们转换成另一种形式。例如,正则表达式通常被转换成状态机。但即使在这种情况下, 转换器仍可用解释器模式实现, 该模式仍是有用的。

实现:


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


14. Template Method(模板方法)  

意图:

定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。TemplateMethod 使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。

适用性:

一次性实现一个算法的不变的部分,并将可变的行为留给子类来实现。

各子类中公共的行为应被提取出来并集中到一个公共父类中以避免代码重复。这是Opdyke 和Johnson所描述过的“重分解以一般化”的一个很好的例子[ OJ93 ]。首先识别现有代码中的不同之处,并且将不同之处分离为新的操作。最后,用一个调用这些新的操作的模板方法来替换这些不同的代码。

控制子类扩展。模板方法只在特定点调用“hook ”操作(参见效果一节),这样就只允许在这些点进行扩展。

实现:


   
   
  1. #!/usr/bin/python
  2. #coding:utf8
  3. '''
  4. Template Method
  5. '''
  6. ingredients = "spam eggs apple"
  7. line = '-' * 10
  8. # Skeletons
  9. def iter_elements( getter, action):    
  10.      """Template skeleton that iterates items"""     
  11.      for element in getter():        
  12.         action(element)    
  13.          print(line) 
  14. def rev_elements( getter, action):
  15.      """Template skeleton that iterates items in reverse order"""     
  16.      for element in getter()[::- 1]:        
  17.         action(element)    
  18.          print(line) 
  19. # Getters
  20. def get_list():    
  21.      return ingredients.split() 
  22. def get_lists():
  23.      return [ list(x) for x i
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值