ck1987 发表于 2017-5-6 11:19:29

模式代码《大话设计模式》Python版代码实现

  查了好多资料,发现还是不全,干脆自己整理吧,至少保证在我的做法正确的,以免误导读者,也是给自己做个记录吧!
  上一周把《谎话设计模式》看完了,对面向对象技巧有了新的解理,对于一个在C下写代码比拟多、偶尔会用到一些脚本语言写脚本的人来讲,是很开阔眼界。《谎话设计模式》的代码用使C#写成的,而在本人接触到的面向对象语言中,只对C++和Python还算解了,为了加深对各个模式的解理,我在网上下载了一个C++版的源代码,并根据自己的解理边读这本书边手动实际C++源代码,同时将其改写成了Python代码,算是一箭三雕吧。
  由于这些代码的的目是示展各个设计模式而非成完一个体具的杂复任务,基于C++本版改写,例子的取材也和《谎话设计模式》基本雷同,再加上个人平水限有,因此这些Python版代码写的比拟简略,虽然能跑起来是不假,不过不免有bug,而且现实也不一定最优,C++的滋味比拟浓而够不pythonic,还请妙手容纳教正。不过我还是尽量把或多或少有些pythonic的货色放在个每模式的“代码特色”部份停止示展,而这个“代码特色”里也不仅仅是pythonic的货色。
  用使Python本版为2.6。
  配图样同摘自《谎话设计模式》,因此是C#风格的UML图类,为了便于排版经已缩小了。
  一、简略工厂模式

  模式特色:工厂根据条件发生不同功能的类。
  序程实例:四则运算计算器,根据用户的输入发生响应的运算类,用这个运算类处置体具的运算。
  代码特色:C/C++中的switch...case...分支用使字典的方法取代。
  用使异常机制对除数为0的情况停止处置。

简略工厂模式
class Operation:
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 = self.op1/self.op2
return result
except:
print "error:divided by zero."
return 0
class OperationUndef(Operation):
def GetResult(self):
print "Undefine operation."
return 0
class OperationFactory:
operation = {}
operation["+"] = OperationAdd();
operation["-"] = OperationSub();
operation["*"] = OperationMul();
operation["/"] = OperationDiv();
def createOperation(self,ch):      
if ch in self.operation:
op = self.operation
else:
op = OperationUndef()
return op
if __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 0
class CashNormal(CashSuper):
def AcceptCash(self,money):
return money
class CashRebate(CashSuper):
discount = 0
def __init__(self,ds):
self.discount = ds
def AcceptCash(self,money):
return money * self.discount
class 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 money
class 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:for normal,for 80% discount for 300 -100.")
if ctype in strategy:
cc = strategy
else:
print "Undefine type.Use normal mode."
cc = strategy]
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 0
class 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 temp
class StudentFactory(LeiFengFactory):
def CreateLeiFeng(self):
temp = Student()
return temp
class VolenterFactory(LeiFengFactory):
def CreateLeiFeng(self):
temp = Volenter()
return temp
if __name__ == "__main__":
sf = StudentFactory()
s=sf.CreateLeiFeng()
s.Sweep()
sdf = VolenterFactory()
sd=sdf.CreateLeiFeng()
sd.Sweep()



  六、原型模式

  模式特色:用原型实例指定创立对象的种类,并且通过拷贝这些原型创立新的对象。
  序程实例:从简历原型,成生新的简历
  代码特色:简历类Resume供提的Clone()方法其实是不并真正的Clone,只是为已存在对象加增了一次引用。
  Python为对象供提的copy模块中的copy方法和deepcopy方法经已现实了原型模式,但由于例子的层次较浅,两者看不出别区。

原型模式
import copy
class WorkExp:
place=""
year=0
class Resume:
name = ''
age = 0
def __init__(self,n):
self.name = n
def SetAge(self,a):
self.age = a
def SetWorkExp(self,p,y):
self.place = p
self.year = y
def Display(self):
print self.age
print self.place
print self.year
def Clone(self):
#现实不是“克隆”,只是返回了自身
return self
if __name__ == "__main__":
a = Resume("a")
b = a.Clone()
c = copy.copy(a)
d = copy.deepcopy(a)
a.SetAge(7)
b.SetAge(12)
c.SetAge(15)
d.SetAge(18)
a.SetWorkExp("PrimarySchool",1996)
b.SetWorkExp("MidSchool",2001)
c.SetWorkExp("HighSchool",2004)
d.SetWorkExp("University",2007)
a.Display()
b.Display()
c.Display()
d.Display()



  七、模板方法模式

  模式特色:定义一个操纵中的算法骨架,将一些骤步迟延至类子中。
  序程实例:考试时用使同一种考卷(类父),不同生学上交自己填写的试卷(类子方法的现实)
  代码特色:无

模板方法模式
class TestPaper:
def TestQuestion1(self):
print "Test1:A. B. C. D."
print "(%s)" %self.Answer1()
def TestQuestion2(self):
print "Test1:A. B. C. D."
print "(%s)" %self.Answer2()
def Answer1(self):
return ""
def Answer2(self):
return ""
class TestPaperA(TestPaper):
def Answer1(self):
return "B"
def Answer2(self):
return "C";
class TestPaperB(TestPaper):
def Answer1(self):
return "D"
def Answer2(self):
return "D";
if __name__ == "__main__":
s1 = TestPaperA()
s2 = TestPaperB()
print "student 1"
s1.TestQuestion1()
s1.TestQuestion2()
print "student 2"
s2.TestQuestion1()
s2.TestQuestion2()



  八、外观模式

  模式特色:为一组调用供提致一的口接。
  序程实例:口接将几种调用离分合组成为两组,用户通过口接调用其中的一组。
  代码特色:无

外观模式
class SubSystemOne:
def MethodOne(self):
print "SubSysOne"
class SubSystemTwo:
def MethodTwo(self):
print "SubSysTwo"
class SubSystemThree:
def MethodThree(self):
print "SubSysThree"
class SubSystemFour:
def MethodFour(self):
print "SubSysFour"

class Facade:
def __init__(self):
self.one = SubSystemOne()
self.two = SubSystemTwo()
self.three = SubSystemThree()
self.four = SubSystemFour()
def MethodA(self):
print "MethodA"
self.one.MethodOne()
self.two.MethodTwo()
self.four.MethodFour()
def MethodB(self):
print "MethodB"
self.two.MethodTwo()
self.three.MethodThree()
if __name__ == "__main__":
facade = Facade()
facade.MethodA()
facade.MethodB()



  九、制作者模式

  模式特色:将一个杂复对象的构建(Director)与它的示表(Builder)离分,使得样同的构建进程可以创立不同的示表(ConcreteBuilder)。
  序程实例:“画”出一个四肢健全(头手身腿)的人小
  代码特色:无

制作者模式
class Person:
def CreateHead(self):
pass
def CreateHand(self):
pass
def CreateBody(self):
pass
def CreateFoot(self):
pass
class 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):
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("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):
pass
class IDepartment:
def GetDepartment(self):
pass
def InsertDepartment(self):
pass
class 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):
pass
class AccessFactory(IFactory):
def CreateUser(self):
temp=CAccessUser()
return temp
def CreateDepartment(self):
temp = CAccessDepartment()
return temp
class SqlFactory(IFactory):
def CreateUser(self):
temp = CSqlUser()
return temp
def CreateDepartment(self):
temp = CSqlDepartment()
return temp
if __name__ == "__main__":
factory = SqlFactory()
user=factory.CreateUser()
depart=factory.CreateDepartment()
user.GetUser()
depart.GetDepartment()



  十二、状态模式
  
  模式特色:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
  序程实例:描述一个序程员的作工状态,当要需改变状态时发生改变,不同状态下的方法现实不同
  代码特色:无

状态模式
class State:
def WirteProgram(self):
pass
class 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()



  十三、适配器模式

  模式特色:将一个类的口接转换成为客户希望的另外一个口接。
  序程实例:用户通过适配器用使一个类的方法。
  代码特色:无

    每日一道理
心的本色该是如此。成,如朗月照花,深潭微澜,不论顺逆,不论成败的超然,是扬鞭策马,登高临远的驿站;败,仍滴水穿石,汇流入海,有穷且益坚,不坠青云的傲岸,有“将相本无主,男儿当自强”的倔强。荣,江山依旧,风采犹然,恰沧海巫山,熟视岁月如流,浮华万千,不屑过眼烟云;辱,胯下韩信,雪底苍松,宛若羽化之仙,知退一步,海阔天空,不肯因噎废食。

适配器模式
class Target:
def Request():
print "common request."
class Adaptee(Target):
def SpecificRequest(self):
print "specific request."
class Adapter(Target):
def __init__(self,ada):
self.adaptee = ada
def Request(self):
self.adaptee.SpecificRequest()
if __name__ == "__main__":
adaptee = Adaptee()
adapter = Adapter(adaptee)
adapter.Request()



  十四、备忘录模式

  模式特色:在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,以后可以将对象恢复到这个状态。
  序程实例:将Originator对象的状态封装成Memo对象保存在Caretaker内
  代码特色:无

备忘录模式
class Originator:
def __init__(self):
self.state = ""
def Show(self):
print self.state
def CreateMemo(self):
return Memo(self.state)
def SetMemo(self,memo):
self.state = memo.state
class Memo:
state= ""
def __init__(self,ts):
self.state = ts
class Caretaker:
memo = ""
if __name__ == "__main__":
on = Originator()
on.state = "on"
on.Show()
c = Caretaker()
c.memo=on.CreateMemo()
on.state="off"
on.Show()
on.SetMemo(c.memo)
on.Show()



  十五、合组模式
  
  模式特色:将对象合组成成树形结构以示表“部份-整体”的层次结构
  序程实例:公司人员的组织结构
  代码特色:无

合组模式
class Component:
def __init__(self,strName):
self.m_strName = strName
def Add(self,com):
pass
def Display(self,nDepth):
pass
class Leaf(Component):
def Add(self,com):
print "leaf can't add"
def Display(self,nDepth):
strtemp = ""
for i in range(nDepth):
strtemp=strtemp+"-"
strtemp=strtemp+self.m_strName
print strtemp
class Composite(Component):
def __init__(self,strName):
self.m_strName = strName
self.c = []
def Add(self,com):
self.c.append(com)
def Display(self,nDepth):
strtemp=""
for i in range(nDepth):
strtemp=strtemp+"-"
strtemp=strtemp+self.m_strName
print strtemp
for com in self.c:
com.Display(nDepth+2)
if __name__ == "__main__":
p = Composite("Wong")
p.Add(Leaf("Lee"))
p.Add(Leaf("Zhao"))
p1 = Composite("Wu")
p1.Add(Leaf("San"))
p.Add(p1)
p.Display(1);



  十六、迭代器模式
  
  模式特色:供提方法顺序问访一个聚合对象中各元素,而又不暴露该对象的内部示表
  说明:这个模式没有写代码现实,原因是用使Python的列表和for ... in list就能够成完不同类型对象聚合的迭代功能了。
  十七、单例模式
  
  模式特色:保证类仅有一个实例,并供提一个问访它的全局问访点。
  说明:     为了现实单例模式费了不少工夫,后来查到一篇博文对此有很详细的介绍,而且现实方法也很丰富,通过对代码的学习可以解了更多Python的用法。以下的代码出自GhostFromHeaven的专栏,地址:http://blog.csdn.net/ghostfromheaven/article/details/7671853。不过正如其作者在Python单例模式终极版所说:
  我要问的是,Python真的要需单例模式吗?我指像其他编程语言中的单例模式。
  答案是:不要需!
  因为,Python有模块(module),最pythonic的单例典范。
  模块在在一个应用序程中只有一份,它本身就是单例的,将你所要需的属性和方法,直接暴露在模块中变成模块的全局变量和方法即可!

单例模式(四种方法)
#-*- encoding=utf-8 -*-
print '----------------------方法1--------------------------'
#方法1,现实__new__方法
#并在将一个类的实例绑定到类变量_instance上,
#如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
#如果cls._instance不为None,直接返回cls._instance
class 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._instance
class MyClass(Singleton):
a = 1
one = MyClass()
two = MyClass()
two.a = 3
print one.a
#3
#one和two完全雷同,可以用id(), ==, is检测
print id(one)
#29097904
print id(two)
#29097904
print one == two
#True
print one is two
#True
print '----------------------方法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 ob
class MyClass2(Borg):
a = 1
one = MyClass2()
two = MyClass2()
#one和two是两个不同的对象,id, ==, is对比结果可看出
two.a = 3
print one.a
#3
print id(one)
#28873680
print id(two)
#28873712
print one == two
#False
print one is two
#False
#但是one和two具有雷同的(同一个__dict__属性),见:
print id(one.__dict__)
#30104000
print id(two.__dict__)
#30104000
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._instance
class MyClass3(object):
__metaclass__ = Singleton2
one = MyClass3()
two = MyClass3()
two.a = 3
print one.a
#3
print id(one)
#31495472
print id(two)
#31495472
print one == two
#True
print one is two
#True
print '----------------------方法4--------------------------'
#方法4:也是方法1的升级(高级)本版,
#用使装饰器(decorator),
#这是一种更pythonic,更elegant的方法,
#单例类本身根本不知道自己是单例的,因为他本身(自己的代码)是不并单例的
def singleton(cls, *args, **kw):
instances = {}
def _singleton():
if cls not in instances:
instances = cls(*args, **kw)
return instances
return _singleton
@singleton
class MyClass4(object):
a = 1
def __init__(self, x=0):
self.x = x
one = MyClass4()
two = MyClass4()
two.a = 3
print one.a
#3
print id(one)
#29660784
print id(two)
#29660784
print one == two
#True
print one is two
#True
one.x = 1
print one.x
#1
print two.x
#1



  十八、桥接模式
  
  模式特色:将抽象部份与它的现实部份离分,使它们都可以独立地变化。
  序程实例:两种品牌的手机,要求它们都可以运行游戏和通讯录两个件软,而不是为个每品牌的手机都独立编写不同的件软。
  代码特色:虽然用使了object的新型类,不过在这里不是必须的,是对在Python2.2之后“尽量用使新型类”的建议的遵从示范。

桥接模式
class HandsetSoft(object):
def Run(self):
pass
class HandsetGame(HandsetSoft):
def Run(self):
print "Game"
class HandsetAddressList(HandsetSoft):
def Run(self):
print "Address List"
class HandsetBrand(object):
def __init__(self):
self.m_soft = None
def SetHandsetSoft(self,temp):
self.m_soft= temp
def Run(self):
pass
class HandsetBrandM(HandsetBrand):
def Run(self):
if not (self.m_soft == None):
print "BrandM"
self.m_soft.Run()
class HandsetBrandN(HandsetBrand):
def Run(self):
if not (self.m_soft == None):
print "BrandN"
self.m_soft.Run()
if __name__ == "__main__":
brand = HandsetBrandM()
brand.SetHandsetSoft(HandsetGame())
brand.Run()
brand.SetHandsetSoft(HandsetAddressList())
brand.Run()   



  十九、命令模式

  模式特色:将请求封装成对象,从而使可用不同的请求对客户停止参数化;对请求排队或记录请求日志,以及支持可撤消的操纵。
  序程实例:烧烤店有两种食物,羊肉串和鸡翅。客户向服务员点单,服务员将点好的单告诉大厨,由大厨停止烹饪。
  代码特色:注意在遍历列表时不要用注释的方法删除,否则会出现bug。bug示例序程附在后面,我认为这是因为remove打乱了for迭代查询列表的顺序致导的。

命令模式
class Barbucer:
def MakeMutton(self):
print "Mutton"
def MakeChickenWing(self):
print "Chicken Wing"
class Command:
def __init__(self,temp):
self.receiver=temp
def ExecuteCmd(self):
pass
class BakeMuttonCmd(Command):
def ExecuteCmd(self):
self.receiver.MakeMutton()
class ChickenWingCmd(Command):
def ExecuteCmd(self):
self.receiver.MakeChickenWing()
class Waiter:
def __init__(self):
self.order =[]
def SetCmd(self,command):
self.order.append(command)
print "Add Order"
def Notify(self):
for cmd in self.order:
#self.order.remove(cmd)
#lead to a bug
            cmd.ExecuteCmd()

if __name__ == "__main__":
barbucer=Barbucer()
cmd=BakeMuttonCmd(barbucer)
cmd2=ChickenWingCmd(barbucer)
girl=Waiter()
girl.SetCmd(cmd)
girl.SetCmd(cmd2)
girl.Notify()



  在for中remove会致导bug的示展代码:

bug
c=]
for i in c:
print i
c.remove(i)
#output:
#0
#2



  二十、责职链模式
  
  模式特色:使多个对象都有机会处置请求,从而防止发送者和接收者的耦合关系。将对象连成链并沿着这条链传递请求直到被处置。
  序程实例:请假和加薪等请求发给上级,如果上级无权决议,那么递交给上级的上级。
  代码特色:无

责职链模式
class Request:
def __init__(self,tcontent,tnum):
self.content = tcontent
self.num = tnum
class Manager:
def __init__(self,temp):
self.name = temp
def SetSuccessor(self,temp):
self.manager = temp
def GetRequest(self,req):
pass
class 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):
pass
class Colleague:
def __init__(self,temp):
self.mediator = temp
class Colleague1(Colleague):
def Send(self,message):
self.mediator.Send(message,self)
def Notify(self,message):
print "Colleague1 get a message:%s" %message
class Colleague2(Colleague):
def Send(self,message):
self.mediator.Send(message,self)
def Notify(self,message):
print "Colleague2 get a message:%s" %message
class 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()方法统计引用计数是因为有的对象可能在别处被隐式的引用,从而加增了引用计数。 

享元模式
import sys
class WebSite:
def Use(self):
pass
class ConcreteWebSite(WebSite):
def __init__(self,strName):
self.name = strName
def Use(self,user):
print "Website type:%s,user:%s" %(self.name,user)
class UnShareWebSite(WebSite):
def __init__(self,strName):
self.name = strName
def Use(self,user):
print "UnShare Website type:%s,user:%s" %(self.name, user)
class WebFactory:
def __init__(self):
test = ConcreteWebSite("test")
self.webtype ={"test":test}
self.count = {"test":0}
def GetWeb(self,webtype):
if webtype not in self.webtype:
temp = ConcreteWebSite(webtype)
self.webtype = temp
self.count =1
else:
temp = self.webtype
self.count = self.count+1
return temp
def GetCount(self):
for key in self.webtype:
#print "type: %s, count:%d" %(key,sys.getrefcount(self.webtype))
print "type: %s, count:%d " %(key,self.count)
if __name__ == "__main__":
f = WebFactory()
ws=f.GetWeb("blog")
ws.Use("Lee")
ws2=f.GetWeb("show")
ws2.Use("Jack")
ws3=f.GetWeb("blog")
ws3.Use("Chen")
ws4=UnShareWebSite("TEST")
ws4.Use("Mr.Q")
print f.webtype
f.GetCount()




  二十三、解释器模式
  
  模式特色:给定一个语言,定义它的文法的一种示表,并定义一个解释器,这个解释器用使该示表来解释语言中的句子。
  序程实例:(只是模式特色的最简略示范)
  代码特色:无

解释器模式
class Context:
def __init__(self):
self.input=""
self.output=""
class AbstractExpression:
def Interpret(self,context):
pass
class Expression(AbstractExpression):
def Interpret(self,context):
print "terminal interpret"
class NonterminalExpression(AbstractExpression):
def Interpret(self,context):
print "Nonterminal interpret"
if __name__ == "__main__":
context= ""
c = []
c = c +
c = c +
c = c +
c = c +
for a in c:
a.Interpret(context)



  二十四、问访者模式
  
  模式特色:示表一个作于用某对象结构中的各元素的操纵。它使你可以在不改变各元素的类的前提下定义作于用这些元素的新操纵。
  序程实例:对于男人和女人(接受问访者的元素,ObjectStructure于用穷举这些元素),不同的遭遇(体具的问访者)引发两种对象的不同行为。
  代码特色:无

问访者模式
# -*- coding: UTF-8 -*-
class Person:
def Accept(self,visitor):
pass
class Man(Person):
def Accept(self,visitor):
visitor.GetManConclusion(self)
class Woman(Person):
def Accept(self,visitor):
visitor.GetWomanConclusion(self)
class Action:
def GetManConclusion(self,concreteElementA):
pass
def GetWomanConclusion(self,concreteElementB):
pass
class Success(Action):
def GetManConclusion(self,concreteElementA):
print "男人成功时,背后有个伟大的女人"
def GetWomanConclusion(self,concreteElementB):
print "女人成功时,背后有个不成功的男人"
class Failure(Action):
def GetManConclusion(self,concreteElementA):
print "男人失败时,闷头喝酒,谁也不用劝"
def GetWomanConclusion(self,concreteElementB):
print "女人失败时,眼泪汪汪,谁也劝不了"

class ObjectStructure:
def __init__(self):
self.plist=[]
def Add(self,p):
self.plist=self.plist+
def Display(self,act):
for p in self.plist:
p.Accept(act)
if __name__ == "__main__":
os = ObjectStructure()
os.Add(Man())
os.Add(Woman())
sc = Success()
os.Display(sc)
fl = Failure()
os.Display(fl)



  文章结束给大家分享下程序员的一些笑话语录: AdobeFlash拖垮Windows拖垮IE!又拖垮Linux拖垮Ubuntu拖垮FirxEox!还拖垮BSD拖垮MacOS拖垮Safri!简直无所不拖!AdobeFlash滚出网路世界!不要以为市占有率高就可以持续出烂货产品!以后替代品多得是!
页: [1]
查看完整版本: 模式代码《大话设计模式》Python版代码实现