几种常见的设计模式之 python 实现

来源:互联网 发布:ubuntu离线安装软件包 编辑:程序博客网 时间:2024/06/06 20:42
转载借鉴于 五岳

http://www.cnblogs.com/wuyuegb2312/archive/2013/04/09/3008320.html

一、单例模式 -  四种方式

# coding=utf-8# 单例模式(四种方法)#-*- encoding=utf-8 -*-print '----------------------方法1--------------------------'#方法1,实现__new__方法#并在将一个类的实例绑定到类变量_instance上,#如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回#如果cls._instance不为None,直接返回cls._instanceclass Singleton(object):    def __new__(cls, *args, **kw):        if not hasattr(cls, '_instance'):            orig = super(Singleton, cls)            cls._instance = orig.__new__(cls, *args, **kw)        return cls._instanceclass MyClass(Singleton):    a = 1one = MyClass()two = MyClass()two.a = 3print one.aprint id(one)print id(two)print one == twoprint one is twoprint '----------------------方法2--------------------------'#   方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)#   同一个类的所有实例天然拥有相同的行为(方法),#   只需要保证同一个类的所有实例具有相同的状态(属性)即可#   所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)#   可参看:http://code.activestate.com/recipes/66531/class Borg(object):    _state = {}    def __new__(cls, *args, **kw):        ob = super(Borg, cls).__new__(cls, *args, **kw)        ob.__dict__ = cls._state        return obclass MyClass2(Borg):    a = 1one = MyClass2()two = MyClass2()#one和two是两个不同的对象,id, ==, is对比结果可看出two.a = 3print one.aprint id(one)print id(two)print one == twoprint one is twoprint id(one.__dict__)print id(two.__dict__)print '----------------------方法3--------------------------'#   方法3:本质上是方法1的升级(或者说高级)版#   使用__metaclass__(元类)的高级python用法class Singleton2(type):    def __init__(cls, name, bases, dict):        super(Singleton2, cls).__init__(name, bases, dict)        cls._instance = None    def __call__(cls, *args, **kw):        if cls._instance is None:            cls._instance = super(Singleton2, cls).__call__(*args, **kw)        return cls._instanceclass MyClass3(object):    __metaclass__ = Singleton2one = MyClass3()two = MyClass3()two.a = 3print one.aprint id(one)print id(two)print one == twoprint one is twoprint '----------------------方法4--------------------------'#   方法4:也是方法1的升级(高级)版本,#   使用装饰器(decorator),#   这是一种更pythonic,更elegant的方法,#   单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的def singleton(cls, *args, **kw):    instances = {}    def _singleton():        if cls not in instances:            instances[cls] = cls(*args, **kw)        return instances[cls]    return _singleton@singletonclass MyClass4(object):    a = 1    def __init__(self, x=0):        self.x = xone = MyClass4()two = MyClass4()two.a = 3print one.aprint id(one)print id(two)print one == twoprint one is twoone.x = 1print one.xprint two.x


二、代理模式

# coding:utf-8'''代理模式模式特点:为其他对象提供一种代理以控制对这个对象的访问。程序实例:同模式特点描述。'''class Interface :    def Request(self):        return 0class RealSubject(Interface):    def Request(self):        print "Real request."class Proxy(Interface):    def Request(self):        self.real = RealSubject()        self.real.Request()if __name__ == "__main__":    p = Proxy()    p.Request()

三、观察者模式

# coding:utf-8'''观察者模式模式特点:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者。程序实例:公司里有两种上班时趁老板不在时偷懒的员工:看NBA的和看股票行情的,并且事先让老板秘书当老板出现时通知他们继续做手头上的工作。程序特点:无'''# 抽象类class Observer:    def __init__(self,strname,strsub):        self.name = strname        self.sub = strsub    def Update(self):        pass# 具体类class StockObserver(Observer):    #no need to rewrite __init__()    def Update(self):        print "%s:%s,stop watching Stock and go on work!" %(self.name,self.sub.action)# 具体类class NBAObserver(Observer):    def Update(self):        print "%s:%s,stop watching NBA and go on work!" %(self.name,self.sub.action)# 相当于消息更新接口class SecretaryBase:    def __init__(self):        self.observers = []    def Attach(self,new_observer):        pass    def Notify(self):        pass# 具体接口class Secretary(SecretaryBase):    def Attach(self,new_observer):        self.observers.append(new_observer)    def Notify(self):        for p in self.observers:            p.Update()if __name__ == "__main__":    p = Secretary()    s1 = StockObserver("observer1",p)    s2 = NBAObserver("observer2",p)    p.Attach(s1)    p.Attach(s2)    p.action = "warning: BOSS is coming! "    p.Notify()

四、适配器模式

# coding:utf-8'''适配器模式模式特点:将一个类的接口转换成为客户希望的另外一个接口。程序实例:用户通过适配器使用一个类的方法。代码特点:无所谓适配器模式是指是一种接口适配技术,它可通过某个类来使用另一个接口与之不兼容的类,运用此模式,两个类的接口都无需改动。适配器模式主要应用于希望复用一些现存的类,但是接口又与复用环境要求不一致的情况,比如在需要对早期代码复用一些功能等应用上很有实际价值。其中Target是用户期望的标准类,而Adaptee是我们需要匹配的类,二者通过Adapter匹配起来。'''# 期望输出类class Target(object):    def request(self):        print 'Target request'# 被适配类class Adaptee(object):    def specialRequest(self):        print 'Adaptee specialRequest'# 适配器class Adpater(object):    def __init__(self, adpatee):        self.adpatee = adpatee    def request(self):        self.adpatee.specialRequest()if __name__ == '__main__':    objects = []    a = Target()    b = Adaptee()    objects.append(a)    objects.append(Adpater(b))  # 适配接口    for obj in objects:        obj.request()           # 调用相同接口'''输出:C:\Python27\python.exe E:/codepy/designMode/adapterMode.pyTarget requestAdaptee specialRequest调用了相同的接口,但是却实现了特殊类的输出,即被适配的类通过通用接口也可以输出'''

五、简单工厂模式

# coding:utf-8'''简单工厂模式模式特点:工厂根据条件产生不同功能的类。         只生产单一类别的东西程序实例:四则运算计算器,根据用户的输入产生相应的运算类,用这个运算类处理具体的运算。'''class Operation(object):    def GetResult(self):        pass# '+'操作符class OperationAdd(Operation):    def GetResult(self):        return self.op1 + self.op2# '-'操作符class OperationSub(Operation):    def GetResult(self):        return self.op1 - self.op2# '*'操作符class OperationMul(Operation):    def GetResult(self):        return self.op1 + self.op2# '/'操作符class OperationDiv(Operation):    def GetResult(self):        try:            # 浮点除法            result = float(self.op1)/self.op2            return result        except:            print "Error: divided by 0."            return# 未定义运算符class OperationUnknown(Operation):    def GetResult(self):        return "this is an unknown operation"class OperationFactory(object):    ops = {}    ops['+'] = OperationAdd()    ops['-'] = OperationSub()    ops['*'] = OperationMul()    ops['/'] = OperationDiv()    def CreateOp(self, ch):        if ch in self.ops:            op = self.ops[ch]        else:            op = OperationUnknown()        return op# 测试if __name__ == '__main__':    op1 = input("a: ")    op = raw_input("Operation: ")    op2 = input("b: ")    factory = OperationFactory()    cal = factory.CreateOp(op)    cal.op1 = op1    cal.op2 = op2    print cal.GetResult()


六、抽象工厂模式

# coding:utf-8'''抽象工厂模式模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。程序实例:提供对不同的数据库访问的支持。     IUser和IDepartment是两种不同的抽象产品,它们都有mysql 和redis这两种不同的实现;         IFactory是产生IUser和IDepartment的抽象工厂,         根据具体实现(mysqlFactory和redisFactory)产生对应的具体的对象(mysqlUser与mysqlDepartment或者redisUser与redisDepartment)。抽象工厂与简单工程的区别:    简单工厂 :用来生产同一等级结构中的任意产品。(对于增加新的产品,无能为力)    工厂方法 :用来生产同一等级结构中的固定产品。(支持增加任意产品)       抽象工厂 :用来生产不同产品族的全部产品。(对于增加新的产品,无能为力;支持增加产品族)       '''# 抽象产品class IUser:    def GetUser(self):        pass    def InsertUser(self):        pass# 抽象产品class IDepartment:    def GetDepartment(self):        pass    def InsertDepartment(self):        pass# 实现class mysqlUser(IUser):    def GetUser(self):        print "mysql GetUser"    def InsertUser(self):        print "mysql InsertUser"# 实现class mysqlDepartment(IDepartment):    def GetDepartment(self):        print "mysql GetDepartment"    def InsertDepartment(self):        print "mysql InsertDepartment"# 实现class redisUser(IUser):    def GetUser(self):        print "redis GetUser"    def InsertUser(self):        print "redis InsertUser"# 实现class redisDepartment(IDepartment):    def GetDepartment(self):        print "redis GetDepartment"    def InsertDepartment(self):        print "redis InsertDepartment"# 抽象工厂class IFactory:    def CreateUser(self):        pass    def CreateDepartment(self):        pass# 具体工厂class mysqlFactory(IFactory):    def CreateUser(self):        temp = mysqlUser()        return temp    def CreateDepartment(self):        temp = mysqlDepartment()        return temp# 具体工厂class redisFactory(IFactory):    def CreateUser(self):        temp = redisUser()        return temp    def CreateDepartment(self):        temp = redisDepartment()        return tempif __name__ == "__main__":    factory = redisFactory()    user = factory.CreateUser()    depart = factory.CreateDepartment()    user.GetUser()    depart.GetDepartment()

七、生产者-消费者模式 (采用协程实现)来自廖大:

https://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/0013868328689835ecd883d910145dfa8227b539725e5ed000


import timedef consumer():    r = ''    while True:        n = yield r        if not n:            return        print('[CONSUMER] Consuming %s...' % n)        time.sleep(1)        r = '200 OK'def produce(c):    c.next()    n = 0    while n < 5:        n = n + 1        print('[PRODUCER] Producing %s...' % n)        r = c.send(n)        print('[PRODUCER] Consumer return: %s' % r)    c.close()if __name__=='__main__':    c = consumer()    produce(c)

结果:

[PRODUCER] Producing 1...[CONSUMER] Consuming 1...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 2...[CONSUMER] Consuming 2...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 3...[CONSUMER] Consuming 3...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 4...[CONSUMER] Consuming 4...[PRODUCER] Consumer return: 200 OK[PRODUCER] Producing 5...[CONSUMER] Consuming 5...[PRODUCER] Consumer return: 200 OK