python为语言的设计模式
摘录自
http://www.cnblogs.com/wuyuegb2312/archive/2013/04/09/3008320.html
?
一、简单工厂模式
模式特点:工厂根据条件产生不同功能的类。
程序实例:四则运算计算器,根据用户的输入产生相应的运算类,用这个运算类处理具体的运算。
代码特点:C/C++中的switch...case...分支使用字典的方式代替。
使用异常机制对除数为0的情况进行处理。
class Operation: def GetResult(self): passclass OperationAdd(Operation): def GetResult(self): return self.op1 + self.op2class OperationSub(Operation): def GetResult(self): return self.op1 - self.op2class OperationMul(Operation): def GetResult(self): return self.op1 * self.op2class OperationDiv(Operation): def GetResult(self): try: result = self.op1 / self.op2 return result except: print "error:divided by zero." return 0class OperationUndef(Operation): def GetResult(self): print "Undefine operation." return 0class OperationFactory: operation = {} operation["+"] = OperationAdd(); operation["-"] = OperationSub(); operation["*"] = OperationMul(); operation["/"] = OperationDiv(); def createOperation(self, ch): if ch in self.operation: op = self.operation[ch] else: op = OperationUndef() return opif __name__ == "__main__": op = raw_input("operator: ") opa = input("a: ") opb = input("b: ") factory = OperationFactory() cal = factory.createOperation(op) cal.op1 = opa cal.op2 = opb print cal.GetResult()?
?
二、策略模式
模式特点:定义算法家族并且分别封装,它们之间可以相互替换而不影响客户端。
程序实例:商场收银软件,需要根据不同的销售策略方式进行收费
代码特点:不同于同例1,这里使用字典是为了避免关键字不在字典导致bug的陷阱。
class CashSuper: def AcceptCash(self, money): return 0class CashNormal(CashSuper): def AcceptCash(self, money): return moneyclass CashRebate(CashSuper): discount = 0 def __init__(self, ds): self.discount = ds def AcceptCash(self, money): return money * self.discountclass CashReturn(CashSuper): total = 0; ret = 0; def __init__(self, t, r): self.total = t self.ret = r def AcceptCash(self, money): if (money >= self.total): return money - self.ret else: return moneyclass CashContext: def __init__(self, csuper): self.cs = csuper def GetResult(self, money): return self.cs.AcceptCash(money)if __name__ == "__main__": money = input("money:") strategy = {} strategy[1] = CashContext(CashNormal()) strategy[2] = CashContext(CashRebate(0.8)) strategy[3] = CashContext(CashReturn(300, 100)) ctype = input("type:[1]for normal,[2]for 80% discount [3]for 300 -100.") if ctype in strategy: cc = strategy[ctype] else: print "Undefine type.Use normal mode." cc = strategy[1] print "you will pay:%d" % (cc.GetResult(money))?
三、装饰模式
模式特点:动态地为对象增加额外的职责
程序实例:展示一个人一件一件穿衣服的过程。
代码特点:无
class Person: def __init__(self, tname): self.name = tname def Show(self): print "dressed %s" % (self.name)class Finery(Person): componet = None def __init__(self): pass def Decorate(self, ct): self.componet = ct def Show(self): if (self.componet != None): self.componet.Show()class TShirts(Finery): def __init__(self): pass def Show(self): print "Big T-shirt " self.componet.Show()class BigTrouser(Finery): def __init__(self): pass def Show(self): print "Big Trouser " self.componet.Show()if __name__ == "__main__": p = Person("somebody") bt = BigTrouser() ts = TShirts() bt.Decorate(p) ts.Decorate(bt) ts.Show()?
四、代理模式
模式特点:为其他对象提供一种代理以控制对这个对象的访问。
程序实例:同模式特点描述。
代码特点:无
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()?
五、工厂方法模式
模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。
程序实例:基类雷锋类,派生出学生类和志愿者类,由这两种子类完成“学雷锋”工作。子类的创建由雷锋工厂的对应的子类完成。
代码特点:无
class LeiFeng: def Sweep(self): print "LeiFeng sweep"class Student(LeiFeng): def Sweep(self): print "Student sweep"class Volenter(LeiFeng): def Sweep(self): print "Volenter sweep"class LeiFengFactory: def CreateLeiFeng(self): temp = LeiFeng() return tempclass StudentFactory(LeiFengFactory): def CreateLeiFeng(self): temp = Student() return tempclass VolenterFactory(LeiFengFactory): def CreateLeiFeng(self): temp = Volenter() return tempif __name__ == "__main__": sf = StudentFactory() s = sf.CreateLeiFeng() s.Sweep() sdf = VolenterFactory() sd = sdf.CreateLeiFeng() sd.Sweep()?
?
?六、原型模式
模式特点:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
程序实例:从简历原型,生成新的简历
代码特点:简历类Resume提供的Clone()方法其实并不是真正的Clone,只是为已存在对象增加了一次引用。
Python为对象提供的copy模块中的copy方法和deepcopy方法已经实现了原型模式,但由于例子的层次较浅,二者看不出区别。
原型模式
七、模板方法模式
?
模式特点:定义一个操作中的算法骨架,将一些步骤延迟至子类中。
程序实例:考试时使用同一种考卷(父类),不同学生上交自己填写的试卷(子类方法的实现)
代码特点:无
class Paper: def Question1(self): print "1:A. B. C. D." print "(%s)" % self.Answer1() def Question2(self): print "1:A. B. C. D." print "(%s)" % self.Answer2() def Answer1(self): return "" def Answer2(self): return ""class PaperA(Paper): def Answer1(self): return "B" def Answer2(self): return "C";class PaperB(Paper): def Answer1(self): return "D" def Answer2(self): return "D";if __name__ == "__main__": s1 = PaperA() s2 = PaperB() print "student 1" s1.Question1() s1.Question2() print "student 2" s2.Question1() s2.Question2()?
?
?八、外观模式
模式特点:为一组调用提供一致的接口。
程序实例:接口将几种调用分别组合成为两组,用户通过接口调用其中的一组。
代码特点:无
外观模式?
九、建造者模式
?
模式特点:将一个复杂对象的构建(Director)与它的表示(Builder)分离,使得同样的构建过程可以创建不同的表示(ConcreteBuilder)。
程序实例:“画”出一个四肢健全(头身手腿)的小人
代码特点:无
class Person: def CreateHead(self): pass def CreateHand(self): pass def CreateBody(self): pass def CreateFoot(self): passclass ThinPerson(Person): def CreateHead(self): print "thin head" def CreateHand(self): print "thin hand" def CreateBody(self): print "thin body" def CreateFoot(self): print "thin foot"class ThickPerson(Person): def CreateHead(self): print "thick head" def CreateHand(self): print "thick hand" def CreateBody(self): print "thick body" def CreateFoot(self): print "thick foot"class Director: def __init__(self, temp): self.p = temp def Create(self): self.p.CreateHead() self.p.CreateBody() self.p.CreateHand() self.p.CreateFoot()if __name__ == "__main__": p = ThickPerson() d = Director(p) d.Create()?
?
十、观察者模式
模式特点:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者。
程序实例:公司里有两种上班时趁老板不在时偷懒的员工:看NBA的和看股票行情的,并且事先让老板秘书当老板出现时通知他们继续做手头上的工作。
程序特点:无
class Observer: def __init__(self, strname, strsub): self.name = strname self.sub = strsub def Update(self): passclass 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): passclass 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("xh", p) s2 = NBAObserver("wyt", p) p.Attach(s1); p.Attach(s2); p.action = "WARNING:BOSS "; p.Notify()?
十一、抽象工厂模式
模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。
程序实例:提供对不同的数据库访问的支持。
IUser和IDepartment是两种不同的抽象产品,它们都有Access和SQL Server这两种不同的实现;IFactory是产生IUser和IDepartment的抽象工厂,根据具体实现(AccessFactory和SqlFactory)产生对应的具体的对象(CAccessUser与CAccessDepartment,或者CSqlUser与CSqlDepartment)。
代码特点:无
class IUser: def GetUser(self): pass def InsertUser(self): passclass IDepartment: def GetDepartment(self): pass def InsertDepartment(self): passclass CAccessUser(IUser): def GetUser(self): print "Access GetUser" def InsertUser(self): print "Access InsertUser"class CAccessDepartment(IDepartment): def GetDepartment(self): print "Access GetDepartment" def InsertDepartment(self): print "Access InsertDepartment"class CSqlUser(IUser): def GetUser(self): print "Sql GetUser" def InsertUser(self): print "Sql InsertUser"class CSqlDepartment(IDepartment): def GetDepartment(self): print "Sql GetDepartment" def InsertDepartment(self): print "Sql InsertDepartment"class IFactory: def CreateUser(self): pass def CreateDepartment(self): passclass AccessFactory(IFactory): def CreateUser(self): temp = CAccessUser() return temp def CreateDepartment(self): temp = CAccessDepartment() return tempclass SqlFactory(IFactory): def CreateUser(self): temp = CSqlUser() return temp def CreateDepartment(self): temp = CSqlDepartment() return tempif __name__ == "__main__": factory = SqlFactory() user = factory.CreateUser() depart = factory.CreateDepartment() user.GetUser() depart.GetDepartment()?
十二、状态模式
?
模式特点:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
程序实例:描述一个程序员的工作状态,当需要改变状态时发生改变,不同状态下的方法实现不同
代码特点:无
class State: def WirteProgram(self): passclass Work: def __init__(self): self.hour = 9 self.current = ForenoonState() def SetState(self, temp): self.current = temp def WriteProgram(self): self.current.WriteProgram(self)class NoonState(State): def WriteProgram(self, w): print "noon working" if (w.hour < 13): print "fun." else: print "need to rest."class ForenoonState(State): def WriteProgram(self, w): if (w.hour < 12): print "morning working" print "energetic" else: w.SetState(NoonState()) w.WriteProgram()if __name__ == "__main__": mywork = Work() mywork.hour = 9 mywork.WriteProgram() mywork.hour = 14 mywork.WriteProgram()?
十三、适配器模式
?
模式特点:将一个类的接口转换成为客户希望的另外一个接口。
程序实例:用户通过适配器使用一个类的方法。
代码特点:无
适配器模式十四、备忘录模式
模式特点:在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,以后可以将对象恢复到这个状态。
程序实例:将Originator对象的状态封装成Memo对象保存在Caretaker内
代码特点:无
备忘录模式十五、组合模式
?
模式特点:将对象组合成成树形结构以表示“部分-整体”的层次结构
程序实例:公司人员的组织结构
代码特点:无
组合模式?
十六、迭代器模式
模式特点:提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示
说明:这个模式没有写代码实现,原因是使用Python的列表和for ... in list就能够完成不同类型对象聚合的迭代功能了。
?
十七、单例模式
?
模式特点:保证类仅有一个实例,并提供一个访问它的全局访问点。
说明: ? ? 为了实现单例模式费了不少工夫,后来查到一篇博文对此有很详细的介绍,而且实现方式也很丰富,通过对代码的学习可以了解更多Python的用法。以下的代码出自GhostFromHeaven的专栏,地址:http://blog.csdn.net/ghostfromheaven/article/details/7671853。不过正如其作者在单例模式(四种方法)
?
十八、桥接模式
?
模式特点:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
程序实例:两种品牌的手机,要求它们都可以运行游戏和通讯录两个软件,而不是为每个品牌的手机都独立编写不同的软件。
代码特点:虽然使用了object的新型类,不过在这里不是必须的,是对在Python2.2之后“尽量使用新型类”的建议的遵从示范。
桥接模式?
十九、命令模式
模式特点:将请求封装成对象,从而使可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
程序实例:烧烤店有两种食物,羊肉串和鸡翅。客户向服务员点单,服务员将点好的单告诉大厨,由大厨进行烹饪。
代码特点:注意在遍历列表时不要用注释的方式删除,否则会出现bug。bug示例程序附在后面,我认为这是因为remove打乱了for迭代查询列表的顺序导致的。
命令模式在for中remove会导致bug的展示代码:
bug?
二十、职责链模式
模式特点:使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系。将对象连成链并沿着这条链传递请求直到被处理。
程序实例:请假和加薪等请求发给上级,如果上级无权决定,那么递交给上级的上级。
代码特点:无
class Request: def __init__(self, tcontent, tnum): self.content = tcontent self.num = tnumclass Manager: def __init__(self, temp): self.name = temp def SetSuccessor(self, temp): self.manager = temp def GetRequest(self, req): passclass CommonManager(Manager): def GetRequest(self, req): if (req.num >= 0 and req.num < 10): print "%s handled %d request." % (self.name, req.num) else: self.manager.GetRequest(req)class MajorDomo(Manager): def GetRequest(self, req): if (req.num >= 10): print "%s handled %d request." % (self.name, req.num)if __name__ == "__main__": common = CommonManager("Zhang") major = MajorDomo("Lee") common.SetSuccessor(major) req = Request("rest", 33) common.GetRequest(req) req2 = Request("salary", 3) common.GetRequest(req2)?
?
二十一、中介者模式
模式特点:用一个对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。
程序实例:两个对象通过中介者相互通信
代码特点:无
?
class Mediator: def Send(self, message, col): passclass Colleague: def __init__(self, temp): self.mediator = tempclass Colleague1(Colleague): def Send(self, message): self.mediator.Send(message, self) def Notify(self, message): print "Colleague1 get a message:%s" % messageclass Colleague2(Colleague): def Send(self, message): self.mediator.Send(message, self) def Notify(self, message): print "Colleague2 get a message:%s" % messageclass ConcreteMediator(Mediator): def Send(self, message, col): if (col == col1): col2.Notify(message) else: col1.Notify(message)if __name__ == "__main__": m = ConcreteMediator() col1 = Colleague1(m) col2 = Colleague1(m) m.col1 = col1 m.col2 = col2 col1.Send("How are you?"); col2.Send("Fine.");
?
?
二十二、享元模式
?
模式特点:运用共享技术有效地支持大量细粒度的对象。
程序实例:一个网站工厂,根据用户请求的类别返回相应类别的网站。如果这种类别的网站已经在服务器上,那么返回这种网站并加上不同用户的独特的数据;如果没有,那么生成一个。
代码特点:为了展示每种网站的由用户请求的次数,这里为它们建立了一个引用次数的字典。
之所以不用Python的sys模块中的sys.getrefcount()方法统计引用计数是因为有的对象可能在别处被隐式的引用,从而增加了引用计数。?
享元模式?
二十三、解释器模式
?
模式特点:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。
程序实例:(只是模式特点的最简单示范)
代码特点:无
解释器模式?
二十四、访问者模式
?
模式特点:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
程序实例:对于男人和女人(接受访问者的元素,ObjectStructure用于穷举这些元素),不同的遭遇(具体的访问者)引发两种对象的不同行为。
代码特点:无
访问者模式