《大话设计模式》Python 版代码实现
?
From:http://www.cnblogs.com/wuyuegb2312/archive/2013/04/09/3008320.html
?
?
一、簡單工廠模式
?
?
模式特點(diǎn):工廠根據(jù)條件產(chǎn)生不同功能的類。
程序?qū)嵗?#xff1a;四則運(yùn)算計(jì)算器,根據(jù)用戶的輸入產(chǎn)生相應(yīng)的運(yùn)算類,用這個(gè)運(yùn)算類處理具體的運(yùn)算。
代碼特點(diǎn):C/C++中的switch...case...分支使用字典的方式代替。
使用異常機(jī)制對(duì)除數(shù)為0的情況進(jìn)行處理。
?
二、策略模式
?
模式特點(diǎn):定義算法家族并且分別封裝,它們之間可以相互替換而不影響客戶端。
程序?qū)嵗?#xff1a;商場收銀軟件,需要根據(jù)不同的銷售策略方式進(jìn)行收費(fèi)
代碼特點(diǎn):不同于同例1,這里使用字典是為了避免關(guān)鍵字不在字典導(dǎo)致bug的陷阱。
?
三、裝飾模式
?
模式特點(diǎn):動(dòng)態(tài)地為對(duì)象增加額外的職責(zé)
程序?qū)嵗?#xff1a;展示一個(gè)人一件一件穿衣服的過程。
代碼特點(diǎn):無
class Person(object):def __init__(self, name):self.name = namedef show(self):print "dressed %s" % self.nameclass Finery(Person):component = Nonedef __init__(self):super(Finery, self).__init__("")passdef decorate(self, ct):self.component = ctdef show(self):if self.component is not None:self.component.show()class TShirts(Finery):def __init__(self):super(TShirts, self).__init__()passdef show(self):print "Big T-shirt "self.component.show()class BigTrouser(Finery):def __init__(self):super(BigTrouser, self).__init__()passdef show(self):print "Big Trouser "self.component.show()def main():p = Person("somebody")bt = BigTrouser()ts = TShirts()bt.decorate(p)ts.decorate(bt)ts.show()if __name__ == "__main__":main()?
四、代理模式
?
模式特點(diǎn):為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問。
程序?qū)嵗?#xff1a;同模式特點(diǎn)描述。
代碼特點(diǎn):無
class Interface(object):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()def main():p = Proxy()p.request()if __name__ == "__main__":main()?
五、工廠方法模式
?
模式特點(diǎn):定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類。這使得一個(gè)類的實(shí)例化延遲到其子類。
程序?qū)嵗?#xff1a;基類雷鋒類,派生出學(xué)生類和志愿者類,由這兩種子類完成“學(xué)雷鋒”工作。子類的創(chuàng)建由雷鋒工廠的對(duì)應(yīng)的子類完成。
代碼特點(diǎn):無
class LeiFeng(object):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 tempdef main():sf = StudentFactory()s = sf.CreateLeiFeng()s.Sweep()sdf = VolenterFactory()sd = sdf.CreateLeiFeng()sd.Sweep()if __name__ == "__main__":main()?
六、原型模式
?
模式特點(diǎn):用原型實(shí)例指定創(chuàng)建對(duì)象的種類,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。
程序?qū)嵗?#xff1a;從簡歷原型,生成新的簡歷
代碼特點(diǎn):簡歷類Resume提供的Clone()方法其實(shí)并不是真正的Clone,只是為已存在對(duì)象增加了一次引用。
Python為對(duì)象提供的copy模塊中的copy方法和deepcopy方法已經(jīng)實(shí)現(xiàn)了原型模式,但由于例子的層次較淺,二者看不出區(qū)別。
import copy class WorkExp:place=""year=0class Resume:name = ''age = 0def __init__(self,n):self.name = ndef SetAge(self,a):self.age = adef SetWorkExp(self,p,y):self.place = pself.year = ydef Display(self):print self.ageprint self.placeprint self.yeardef Clone(self):#實(shí)際不是“克隆”,只是返回了自身return selfdef 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()if __name__ == "__main__":main()?
七、模板方法模式
?
?
模式特點(diǎn):定義一個(gè)操作中的算法骨架,將一些步驟延遲至子類中。
程序?qū)嵗?#xff1a;考試時(shí)使用同一種考卷(父類),不同學(xué)生上交自己填寫的試卷(子類方法的實(shí)現(xiàn))
代碼特點(diǎn):無
模板方法模式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()?
八、外觀模式
?
模式特點(diǎn):為一組調(diào)用提供一致的接口。
程序?qū)嵗?#xff1a;接口將幾種調(diào)用分別組合成為兩組,用戶通過接口調(diào)用其中的一組。
代碼特點(diǎn):無
外觀模式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()?
九、建造者模式
?
?
模式特點(diǎn):將一個(gè)復(fù)雜對(duì)象的構(gòu)建(Director)與它的表示(Builder)分離,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示(ConcreteBuilder)。
程序?qū)嵗?#xff1a;“畫”出一個(gè)四肢健全(頭身手腿)的小人
代碼特點(diǎn):無
建造者模式class Person:def CreateHead(self):passdef CreateHand(self):passdef CreateBody(self):passdef 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 = tempdef Create(self):self.p.CreateHead()self.p.CreateBody()self.p.CreateHand()self.p.CreateFoot()if __name__ == "__main__":p = ThickPerson()d = Director(p)d.Create()?
十、觀察者模式
?
模式特點(diǎn):定義了一種一對(duì)多的關(guān)系,讓多個(gè)觀察對(duì)象同時(shí)監(jiān)聽一個(gè)主題對(duì)象,當(dāng)主題對(duì)象狀態(tài)發(fā)生變化時(shí)會(huì)通知所有觀察者。
程序?qū)嵗?#xff1a;公司里有兩種上班時(shí)趁老板不在時(shí)偷懶的員工:看NBA的和看股票行情的,并且事先讓老板秘書當(dāng)老板出現(xiàn)時(shí)通知他們繼續(xù)做手頭上的工作。
程序特點(diǎn):無
觀察者模式class Observer:def __init__(self,strname,strsub):self.name = strnameself.sub = strsubdef 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()?
十一、抽象工廠模式
?
模式特點(diǎn):提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口,而無需指定它們的類。
程序?qū)嵗?#xff1a;提供對(duì)不同的數(shù)據(jù)庫訪問的支持。
IUser和IDepartment是兩種不同的抽象產(chǎn)品,它們都有Access和SQL Server這兩種不同的實(shí)現(xiàn);IFactory是產(chǎn)生IUser和IDepartment的抽象工廠,根據(jù)具體實(shí)現(xiàn)(AccessFactory和SqlFactory)產(chǎn)生對(duì)應(yīng)的具體的對(duì)象(CAccessUser與CAccessDepartment,或者CSqlUser與CSqlDepartment)。
代碼特點(diǎn):無
抽象工廠模式class IUser:def GetUser(self):passdef InsertUser(self):passclass IDepartment:def GetDepartment(self):passdef 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):passdef CreateDepartment(self):passclass AccessFactory(IFactory):def CreateUser(self):temp=CAccessUser()return tempdef CreateDepartment(self):temp = CAccessDepartment()return tempclass SqlFactory(IFactory):def CreateUser(self):temp = CSqlUser()return tempdef CreateDepartment(self):temp = CSqlDepartment()return tempif __name__ == "__main__":factory = SqlFactory()user=factory.CreateUser()depart=factory.CreateDepartment()user.GetUser()depart.GetDepartment()?
十二、狀態(tài)模式
?
模式特點(diǎn):當(dāng)一個(gè)對(duì)象的內(nèi)在狀態(tài)改變時(shí)允許改變其行為,這個(gè)對(duì)象看起來像是改變了其類。
程序?qū)嵗?#xff1a;描述一個(gè)程序員的工作狀態(tài),當(dāng)需要改變狀態(tài)時(shí)發(fā)生改變,不同狀態(tài)下的方法實(shí)現(xiàn)不同
代碼特點(diǎn):無
狀態(tài)模式class State:def WirteProgram(self):passclass Work:def __init__(self):self.hour = 9self.current = ForenoonState()def SetState(self,temp):self.current = tempdef 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 = 9mywork.WriteProgram()mywork.hour =14mywork.WriteProgram()?
十三、適配器模式
?
?
模式特點(diǎn):將一個(gè)類的接口轉(zhuǎn)換成為客戶希望的另外一個(gè)接口。
程序?qū)嵗?#xff1a;用戶通過適配器使用一個(gè)類的方法。
代碼特點(diǎn):無
適配器模式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 = adadef Request(self):self.adaptee.SpecificRequest()if __name__ == "__main__":adaptee = Adaptee()adapter = Adapter(adaptee)adapter.Request()?
十四、備忘錄模式
?
模式特點(diǎn):在不破壞封裝性的前提下捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài),以后可以將對(duì)象恢復(fù)到這個(gè)狀態(tài)。
程序?qū)嵗?#xff1a;將Originator對(duì)象的狀態(tài)封裝成Memo對(duì)象保存在Caretaker內(nèi)
代碼特點(diǎn):無
備忘錄模式class Originator:def __init__(self):self.state = ""def Show(self):print self.statedef CreateMemo(self):return Memo(self.state)def SetMemo(self,memo):self.state = memo.stateclass Memo:state= ""def __init__(self,ts):self.state = tsclass 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()?
十五、組合模式
?
模式特點(diǎn):將對(duì)象組合成成樹形結(jié)構(gòu)以表示“部分-整體”的層次結(jié)構(gòu)
程序?qū)嵗?#xff1a;公司人員的組織結(jié)構(gòu)
代碼特點(diǎn):無
組合模式class Component:def __init__(self,strName):self.m_strName = strNamedef Add(self,com):passdef Display(self,nDepth):passclass 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_strNameprint strtempclass Composite(Component):def __init__(self,strName):self.m_strName = strNameself.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_strNameprint strtempfor 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);?
十六、迭代器模式
?
模式特點(diǎn):提供方法順序訪問一個(gè)聚合對(duì)象中各元素,而又不暴露該對(duì)象的內(nèi)部表示
說明:這個(gè)模式?jīng)]有寫代碼實(shí)現(xiàn),原因是使用Python的列表和for ... in list就能夠完成不同類型對(duì)象聚合的迭代功能了。
?
十七、單例模式
?
模式特點(diǎn):保證類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
說明: ? ? 為了實(shí)現(xiàn)單例模式費(fèi)了不少工夫,后來查到一篇博文對(duì)此有很詳細(xì)的介紹,而且實(shí)現(xiàn)方式也很豐富,通過對(duì)代碼的學(xué)習(xí)可以了解更多Python的用法。以下的代碼出自GhostFromHeaven的專欄,地址:http://blog.csdn.net/ghostfromheaven/article/details/7671853。不過正如其作者在Python單例模式終極版所說:
我要問的是,Python真的需要單例模式嗎?我指像其他編程語言中的單例模式。
答案是:不需要!
因?yàn)?#xff0c;Python有模塊(module),最pythonic的單例典范。
模塊在在一個(gè)應(yīng)用程序中只有一份,它本身就是單例的,將你所需要的屬性和方法,直接暴露在模塊中變成模塊的全局變量和方法即可!
單例模式(四種方法)#-*- encoding=utf-8 -*- print '----------------------方法1--------------------------' #方法1,實(shí)現(xiàn)__new__方法 #并在將一個(gè)類的實(shí)例綁定到類變量_instance上, #如果cls._instance為None說明該類還沒有實(shí)例化過,實(shí)例化該類,并返回 #如果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._instanceclass MyClass(Singleton):a = 1one = 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 #Trueprint '----------------------方法2--------------------------' #方法2,共享屬性;所謂單例就是所有引用(實(shí)例、對(duì)象)擁有相同的狀態(tài)(屬性)和行為(方法) #同一個(gè)類的所有實(shí)例天然擁有相同的行為(方法), #只需要保證同一個(gè)類的所有實(shí)例具有相同的狀態(tài)(屬性)即可 #所有實(shí)例共享屬性的最簡單最直接的方法就是__dict__屬性指向(引用)同一個(gè)字典(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._statereturn obclass MyClass2(Borg):a = 1one = MyClass2() two = MyClass2()#one和two是兩個(gè)不同的對(duì)象,id, ==, is對(duì)比結(jié)果可看出 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具有相同的(同一個(gè)__dict__屬性),見: print id(one.__dict__) #30104000 print id(two.__dict__) #30104000print '----------------------方法3--------------------------' #方法3:本質(zhì)上是方法1的升級(jí)(或者說高級(jí))版 #使用__metaclass__(元類)的高級(jí)python用法 class Singleton2(type):def __init__(cls, name, bases, dict):super(Singleton2, cls).__init__(name, bases, dict)cls._instance = Nonedef __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 = 3 print one.a #3 print id(one) #31495472 print id(two) #31495472 print one == two #True print one is two #Trueprint '----------------------方法4--------------------------' #方法4:也是方法1的升級(jí)(高級(jí))版本, #使用裝飾器(decorator), #這是一種更pythonic,更elegant的方法, #單例類本身根本不知道自己是單例的,因?yàn)樗旧?自己的代碼)并不是單例的 def singleton(cls, *args, **kw):instances = {}def _singleton():if cls not in instances:instances[cls] = cls(*args, **kw)return instances[cls]return _singleton@singleton class MyClass4(object):a = 1def __init__(self, x=0):self.x = xone = 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?
十八、橋接模式
?
模式特點(diǎn):將抽象部分與它的實(shí)現(xiàn)部分分離,使它們都可以獨(dú)立地變化。
程序?qū)嵗?#xff1a;兩種品牌的手機(jī),要求它們都可以運(yùn)行游戲和通訊錄兩個(gè)軟件,而不是為每個(gè)品牌的手機(jī)都獨(dú)立編寫不同的軟件。
代碼特點(diǎn):雖然使用了object的新型類,不過在這里不是必須的,是對(duì)在Python2.2之后“盡量使用新型類”的建議的遵從示范。
橋接模式class HandsetSoft(object):def Run(self):passclass 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 = Nonedef SetHandsetSoft(self,temp):self.m_soft= tempdef Run(self):passclass 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()?
十九、命令模式
?
模式特點(diǎn):將請(qǐng)求封裝成對(duì)象,從而使可用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤消的操作。
程序?qū)嵗?#xff1a;燒烤店有兩種食物,羊肉串和雞翅。客戶向服務(wù)員點(diǎn)單,服務(wù)員將點(diǎn)好的單告訴大廚,由大廚進(jìn)行烹飪。
代碼特點(diǎn):注意在遍歷列表時(shí)不要用注釋的方式刪除,否則會(huì)出現(xiàn)bug。bug示例程序附在后面,我認(rèn)為這是因?yàn)閞emove打亂了for迭代查詢列表的順序?qū)е碌摹?/p> 命令模式class Barbucer:def MakeMutton(self):print "Mutton"def MakeChickenWing(self):print "Chicken Wing"class Command:def __init__(self,temp):self.receiver=tempdef ExecuteCmd(self):passclass 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 bugcmd.ExecuteCmd()if __name__ == "__main__":barbucer=Barbucer()cmd=BakeMuttonCmd(barbucer)cmd2=ChickenWingCmd(barbucer)girl=Waiter()girl.SetCmd(cmd)girl.SetCmd(cmd2)girl.Notify()
在for中remove會(huì)導(dǎo)致bug的展示代碼:
bugc=[0,1,2,3] for i in c:print ic.remove(i)#output: #0 #2?
二十、職責(zé)鏈模式
?
模式特點(diǎn):使多個(gè)對(duì)象都有機(jī)會(huì)處理請(qǐng)求,從而避免發(fā)送者和接收者的耦合關(guān)系。將對(duì)象連成鏈并沿著這條鏈傳遞請(qǐng)求直到被處理。
程序?qū)嵗?#xff1a;請(qǐng)假和加薪等請(qǐng)求發(fā)給上級(jí),如果上級(jí)無權(quán)決定,那么遞交給上級(jí)的上級(jí)。
代碼特點(diǎn):無
職責(zé)鏈模式class Request:def __init__(self,tcontent,tnum):self.content = tcontentself.num = tnumclass Manager:def __init__(self,temp):self.name = tempdef SetSuccessor(self,temp):self.manager = tempdef 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)?
二十一、中介者模式
?
?
模式特點(diǎn):用一個(gè)對(duì)象來封裝一系列的對(duì)象交互,中介者使各對(duì)象不需要顯示地相互引用,從而使耦合松散,而且可以獨(dú)立地改變它們之間的交互。
程序?qū)嵗?#xff1a;兩個(gè)對(duì)象通過中介者相互通信
代碼特點(diǎn):無
中介者模式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=col1m.col2=col2col1.Send("How are you?");col2.Send("Fine.");?
二十二、享元模式
?
?
模式特點(diǎn):運(yùn)用共享技術(shù)有效地支持大量細(xì)粒度的對(duì)象。
程序?qū)嵗?#xff1a;一個(gè)網(wǎng)站工廠,根據(jù)用戶請(qǐng)求的類別返回相應(yīng)類別的網(wǎng)站。如果這種類別的網(wǎng)站已經(jīng)在服務(wù)器上,那么返回這種網(wǎng)站并加上不同用戶的獨(dú)特的數(shù)據(jù);如果沒有,那么生成一個(gè)。
代碼特點(diǎn):為了展示每種網(wǎng)站的由用戶請(qǐng)求的次數(shù),這里為它們建立了一個(gè)引用次數(shù)的字典。
之所以不用Python的sys模塊中的sys.getrefcount()方法統(tǒng)計(jì)引用計(jì)數(shù)是因?yàn)橛械膶?duì)象可能在別處被隱式的引用,從而增加了引用計(jì)數(shù)。?
享元模式import sysclass WebSite:def Use(self):passclass ConcreteWebSite(WebSite):def __init__(self,strName):self.name = strNamedef Use(self,user):print "Website type:%s,user:%s" %(self.name,user)class UnShareWebSite(WebSite):def __init__(self,strName):self.name = strNamedef 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[webtype] = tempself.count[webtype] =1else:temp = self.webtype[webtype]self.count[webtype] = self.count[webtype]+1return tempdef GetCount(self):for key in self.webtype:#print "type: %s, count:%d" %(key,sys.getrefcount(self.webtype[key]))print "type: %s, count:%d " %(key,self.count[key])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.webtypef.GetCount()?
二十三、解釋器模式
?
模式特點(diǎn):給定一個(gè)語言,定義它的文法的一種表示,并定義一個(gè)解釋器,這個(gè)解釋器使用該表示來解釋語言中的句子。
程序?qū)嵗?#xff1a;(只是模式特點(diǎn)的最簡單示范)
代碼特點(diǎn):無
解釋器模式class Context:def __init__(self):self.input=""self.output=""class AbstractExpression:def Interpret(self,context):passclass 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 + [Expression()]c = c + [NonterminalExpression()]c = c + [Expression()]c = c + [Expression()]for a in c:a.Interpret(context)?
二十四、訪問者模式
?
模式特點(diǎn):表示一個(gè)作用于某對(duì)象結(jié)構(gòu)中的各元素的操作。它使你可以在不改變各元素的類的前提下定義作用于這些元素的新操作。
程序?qū)嵗?#xff1a;對(duì)于男人和女人(接受訪問者的元素,ObjectStructure用于窮舉這些元素),不同的遭遇(具體的訪問者)引發(fā)兩種對(duì)象的不同行為。
代碼特點(diǎn):無
訪問者模式# -*- coding: UTF-8 -*- class Person:def Accept(self,visitor):passclass 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):passdef GetWomanConclusion(self,concreteElementB):passclass Success(Action):def GetManConclusion(self,concreteElementA):print "男人成功時(shí),背后有個(gè)偉大的女人"def GetWomanConclusion(self,concreteElementB):print "女人成功時(shí),背后有個(gè)不成功的男人"class Failure(Action):def GetManConclusion(self,concreteElementA):print "男人失敗時(shí),悶頭喝酒,誰也不用勸"def GetWomanConclusion(self,concreteElementB):print "女人失敗時(shí),眼淚汪汪,誰也勸不了"class ObjectStructure:def __init__(self):self.plist=[]def Add(self,p):self.plist=self.plist+[p]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)?
?
?
總結(jié)
以上是生活随笔為你收集整理的《大话设计模式》Python 版代码实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux异步之信号(signal)机制
- 下一篇: 安装 Python 包时解决 Micro