几种常见的设计模式之 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
阅读全文
0 0
- 几种常见的设计模式之 python 实现
- 几种常见设计模式的JAVA实现例子
- 单例设计模式的几种常见实现方法
- java之 ------ 几种常见的简单设计模式
- 常见的几种设计模式
- 几种常见设计模式的使用
- cocos2dx的几种常见设计模式
- JAVA 几种常见的设计模式
- 几种常见的设计模式
- cocos2dx的几种常见设计模式
- 几种常见的设计模式
- JAVA几种常见的设计模式
- 关于几种常见的设计模式
- 常见的几种设计模式
- JAVA几种常见的设计模式
- 几种常见的设计模式介绍
- 几种常见的设计模式
- 设计模式:几种常见的设计模式
- Thread.sleep/wait
- 程序员应该访问的最佳网站中文版
- 关于x5button的操作
- 【备忘】微信小程序从入门到实践视频教程
- jeesite使用心得(二)
- 几种常见的设计模式之 python 实现
- Nginx配置文件及代理服务器设置
- SQL布尔型盲注思路分析(入门必看)
- 仿scrapy的爬虫框架 (python3.5以上模块化,需要支持async/await语法)
- 查看Linux 是Red Hat,CentOS还是ubuntu
- Java 创建多线程的第二种方式
- 空间应用--固态硬盘的极限挑战
- Linux安装软件的几种方法
- OpenJudge百炼-2799-浮点数格式-C语言-字符串处理