python面向对象之设计模式

 
概念:
设计模式(Design Pattern)是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式的目的:为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。 设计模式使代码编写真正工程化
设计模式是一套被反复使用的、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计模式是为了重用代码、让代码更容易被他人理解、保证代码可靠性。 毫无疑问,设计模式于己于他人于系统都是多赢的,设计模式使代码编制真正工程化,设计模式是软件工程的基石,如同大厦的一块块砖石一样。项目中合理地运用设计模式可以完美地解决很多问题,每种模式在现实中都有相应的原理来与之对应,每种模式都描述了一个在我们周围不断重复发生的问题,以及该问题的核心解决方案,这也是设计模式能被广泛应用的原因。[1]
设计模式有助于对框架结构的理解,成熟的框架通常使用了多种设计模式,如果你熟悉这些设计模式,毫无疑问,你将迅速掌握框架的结构,我们一般开发者如果突然接触EJBSpring等框架,会觉得特别难学、难掌握,那么转而先掌握设计模式,无疑是给了你剖析EJB或J2EE系统的一把利器
设计模式分为三大类:
创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。
结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。
行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。
其实还有两类:并发型模式和线程池模式。
 常用的单例,装饰器,工厂

单例模式

意图
单例模式 单例模式
保证一个类仅有一个实例,并提供一个访问它的全局访问点。
适用性
  • 当类只能有一个实例而且客户可以从一个众所周知的访问点访问它时。
  • 当这个唯一实例应该是通过子类化可扩展的,并且客户应该无需更改代码就能使用一个扩展的实例时。
  • #coding=utf-8

    class Singleton(object):

        def __new__(cls, *args, **kw):#new的cls放前面

            if not hasattr(cls, '_instance'):#如果不存在实例的属性,则新建一个实例,否则返回已有实例

    #每个类只要被实例化,私有属性_instance就会被赋值

    #下面两句,表示使用object.__new__方法生成了Singleton的一个实例

                orig = super(Singleton, cls)#继承父类,super的cls放后面

                cls._instance = orig.__new__(cls, *args, **kw)

                #cls._instance = object.__new__(cls, *args, **kw)  #等价上一句

    #否则返回已有实例

            return cls._instance

     

    #适用范围:配置信息只需要一份时,可以单例,或者大boss只有一个,可用单例

    #资源管理器,回收站,日志

     

     

  • 装饰模式:

     

  • 意图
    装饰模式 装饰模式
    动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。
    适用性
    • 不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    • 处理那些可以撤消的职责。
    • 当不能采用生成子类的方法进行扩充时。一种情况是,可能有大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长。另一种情况可能是因为类定义被隐藏,或类定义不能用于生成子类
    • #encoding=utf-8

    •  

      #代码没有缩进

    • import time

      def deco(func):

      def __deco():

      list=[]

      func(list)

      print list

      return __deco

      @deco

      def myfunc(list):

      list.append(1)

      print " myfunc() called."

      @deco

      def yourfunc(list):

      list.append(2)

      print " yourfunc() called."

      myfunc()

      print "*"*50

      yourfunc()

观察者模式

意图
观察者模式 观察者模式
定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新。
适用性
  • 当一个抽象模型有两个方面, 其中一个方面依赖于另一方面。将这二者封装在独立的对象中以使它们可以各自独立地改变和复用。
  • 当对一个对象的改变需要同时改变其它对象, 而不知道具体有多少对象有待改变。
  • 当一个对象必须通知其它对象,而它又不能假定其它对象是谁。换言之,你不希望这些对象是紧密耦合的。
  • 抽象工厂模式

    抽象工厂模式(Abstract Factory) 抽象工厂模式(Abstract Factory)
    意图
    提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
    适用性
    • 一个系统要独立于它的产品的创建、组合和表示时。
    • 一个系统要由多个产品系列中的一个来配置时。
    • 当你要强调一系列相关的产品对象的设计以便进行联合使用时。
    • 当你提供一个产品类库,而只想显示它们的接口而不是实现时。

工厂模式(单独一个类接收参数,根据参数生成具体的实例)

实例:

#coding=utf-8

class Person:

def __init__(self,gender,name):

self.gender=gender

self.name=name

def getName(self):

return self.name

def getGender(self):

return self.gender

class Male(Person):

def __init__(self,name):

print "hello Mr."+name

class Female(Person):

def __init__(self,name):

print "Hello Miss."+name

class Factory:

def getPerson(self,name,gender):

if gender=="M":

return Male(name)

if gender=="F":

return Female(name)

if __name__=="__main__":

factory=Factory()

person=factory.getPerson("chentao","M")

person=factory.getPerson("lihong","F")

代理模式

意图
代理模式 代理模式
为其他对象提供一种代理以控制对这个对象的访问。
适用性
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一 些可以使用Proxy模式常见情况:
  1. 远程代理(Remote Proxy)为一个对象在不同的地址空间提供局部代表。
  2. 虚代理(Virtual Proxy)根据需要创建开销很大的对象。
  3. 保护代理(Protection Proxy)控制对原始对象的访问。保护代理用于对象应该有不同 的访问权限的时候。
  4. 智能指引(Smart Reference)取代了简单的指针,它在访问对象时执行一些附加操作。 它的典型用途包括:
    • 对指向实际对象的引用计数,这样当该对象没有引用时,可以自动释放它(也称为SmartPointers)。
    • 当第一次引用一个持久对象时,将它装入内存。
    • 在访问一个实际对象前,检查是否已经锁定了它,以确保其他对象不能改变它。
  5. 命令模式

    意图
    命令模式 命令模式
    将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作
    适用性
    • 像上面讨论的MenuItem对象那样,抽象出待执行的动作以参数化某对象。你可用过程语言中的回调(callback)函数表达这种参数化机制。所谓回调函数是指函数先在某处注册,而它将在稍后某个需要的时候被调用。Command模式是回调机制的一个面向对象的替代品。
    • 在不同的时刻指定、排列和执行请求。一个Command对象可以有一个与初始请求无关的生存期。如果一个请求的接收者可用一种与地址空间无关的方式表达,那么就可将负责该请求的命令对象传送给另一个不同的进程并在那儿实现该请求。
    • 支持取消操作。Command的Execute操作可在实施操作前将状态存储起来,在取消操作时这个状态用来消除该操作的影响。Command接口必须添加一个Execute操作,该操作取消上一次Execute调用的效果。执行的命令被存储在一个历史列表中。可通过向后和向前遍历这一列表并分别调用Unexecute和Execute来实现重数不限的“取消”和“重做”。
    • 支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍。在Command接口中添加装载操作和存储操作,可以用来保持变动的一个一致的修改日志。从崩溃中恢复的过程包括从磁盘中重新读入记录下来的命令并用Execute操作重新执行它们。
    • 用构建在原语操作上的高层操作构造一个系统。这样一种结构在支持事务(Transaction)的信息系统中很常见。一个事务封装了对数据的一组变动。Command模式提供了对事务进行建模的方法。Command有一个公共的接口,使得你可以用同一种方式调用所有的事务。同时使用该模式也易于添加新事务以扩展系统。
posted @ 2018-03-21 00:33  定静沉行  阅读(486)  评论(0编辑  收藏  举报