1. 程式人生 > >python大話設計模式

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[ch] 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:[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 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()
複製程式碼

九、建造者模式

 

相關推薦

python大話設計模式

上一週把《大話設計模式》看完了,對面向物件技術有了新的理解,對於一個在C下寫程式碼比較多、偶爾會用到一些指令碼語言寫指令碼的人來說,很是開闊眼界。《大話設計模式》的程式碼使用C#寫成的,而在本人接觸到的面嚮物件語言中,只對C++和Python還算了解,為了加深對各個模

大話設計模式Python版程式碼實現

一、簡單工廠模式 模式特點:工廠根據條件產生不同功能的類。 程式例項:四則運算計算器,根據使用者的輸入產生相應的運算類,用這個運算類處理具體的運算。 程式碼特點:C/C++中的switch...case...分支使用字典的方式代替。      使用異常機制

大話設計模式之觀察者模式

arm eve his watermark observer cts 多個 放下 們的 從前,有個放羊娃。每天都去山上放羊,一天,他認為十分無聊。就想了個捉弄大家尋開心的主意。他向著山下正在種田的農夫們大聲喊:“狼來了!狼來了!救命啊!”農夫們聽到喊聲

Python Selenium設計模式-POM

page apt 按鈕 而已 run waiting 什麽 sep repo 前言 本文就python selenium自動化測試實踐中所需要的POM設計模式進行分享,以便大家在實踐中對POM的特點、應用場景和核心思想有一定的理解和掌握。 為什麽要用POM 基於python

大話設計模式】——淺談設計模式基礎

表示 無用功 隱式 art -s -m 個人 pri one   初學設計模式給我最大的感受是:人類真是偉大啊!單單是設計模式的基礎課程就讓我感受到了強烈的生活氣息。個人感覺《大話設計模式》這本書寫的真好。讓貌似非常晦澀難懂的設計模式變的生活化。趣味化。   以下淺談一

大話設計模式》——讀後感 (4)為別人做嫁衣?——靜態代理模式(1)

即使 pri 為我 div 結構 apple .cn string 想要 什麽是代理模式: 代理模式結構圖: 直接上代碼: GiveGift接口: package com.sjmx.staticProxy; public interface GiveG

大話設計模式》——讀後感 (5)雷鋒依然在人間?——工廠方法模式

pri sys rod 加法 完全 .cn 依賴關系 style 優點 什麽是工廠方法模式: 工廠方法UML結構圖: 從圖中我獲取以下信息: 1、 Product是個接口,而Creator是個抽象類(我還是試試接口) 2、ConcreateProduct和Concret

大話設計模式之依賴倒轉原則

銷售員 bsp foo content interface 客戶 依賴倒轉原則 str 基本 依賴倒轉原則: 定義: 在大話中最重要的兩句話是:抽象不應該依賴與細節,細節應該依賴於抽象。還有一句是:針對接口編程,不要對實現編程。 問題: 類A直接依賴類B。假

大話設計模式C++實現-第17章-適配器模式

req span oid efi cpp endif 對象 adapt sdn 一、UML圖 關鍵詞:Client須要Request()函數,Adaptee提供的是SpecificRequest()函數,Adapter提供一個Request()函數將Ada

大話設計模式》——讀後感 (8)好菜每回味不同——建造者模式之基礎案例(1)

ted builds src ret 分離 args 類圖 rec 方法 建造者模式:是將一個復雜的對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。 建造者模式通常包括下面幾個角色: 1. builder:給出一個抽象接口,以規範產品對象的各個組成成分的

大話設計模式》——讀後感 (10)無盡加班何時休?——狀態模式

mce style ram 依賴 sta 回調 shm 有一點 div 原文定義:    狀態模式:當一個對象的內在狀態改變時允許改變其行為,這個對象看起來像是改變其類【DP】 UML結構圖:    背景:   看到此模式,醞釀了好久才決定對狀態模式進行總結。光

大話設計模式—中介者模式

java string word 實例 發生 scrip ron 成了 維護 中介者模式(Mediator Pattern)是用來減少多個對象和類之間的通信復雜性。這種模式提供了一個中介類,該類通常處理不同類之間的通信,並支持松耦合。使代碼易於維護。中介

大話設計模式》——單一職責原則

有一個 導致 完成 如果能 原因 如果 分離 破壞 一個 單一職責原則(SRP):就一個類而言,應該僅有一個能引起它變化的原因。 如果一個類承擔的職責過多,就等於把這些職責耦合在一起,一個職責的變化可能會削弱或抑制這個類完成其他職責的能力。這種耦合會導致脆弱的設計,當變化發

【行為型模式】《大話設計模式》——讀後感 (15)烤羊肉串引來的思考?——命令模式

xtend nds () con 耦合度 聲明 一個 客戶端 行為型 命令模式:將一個請求封裝為一個對象,從而使得你可用不同的請求對客戶進行參數化;對請求排隊或記錄請求日誌,以及支持可撤銷的操作【DP】 先看代碼吧: Receiver: package com.sj

【行為型模式】《大話設計模式》——讀後感 (16)加薪非要老板批?——職責鏈模式

技術 值方法 param images span pack com 適用場景 rri 職責鏈模式(Chain of Responsibility):使多個對象都有機會處理請求,從而避免請求的發送者和接收者之間的耦合關系。將這些對象連成一條鏈,並沿著這條鏈傳遞該請求,直到有一

<四>讀<<大話設計模式>>之代理模式

flow 編程 運行 應該 nts popu rac gif 通過 代理模式我想大家即便不熟悉也都聽過吧,從字面意思上看就是替別人幹活的,比方代理商。在項目的實際應用中也有非常多地方用到。比方spring通過代理模式生成對象等。 代理模式的書

大話設計模式》——建造者模式

多個 構圖 str 業務邏輯 clas 邏輯 add [] -1 建造者模式結構圖 角色:1、builder:建造者接口。定義了建造一個產品所必須的所有流程。所有的建造者都需要實現該類,以確保實現建造一個產品所需的流程。 2、concreteBuilder:具體建造者。每

java 之 策略模式大話設計模式

src 客戶端代碼 div strategy ring 溫故 bre str disco 溫故而知新,每次讀設計模式都會有不同的體驗,堅持每天一個設計模式,直到熟練運用設計模式。 策略模式定義了很多完成相同工作的算法,但實現不同,它可以以相同的方式調用所有的算法,減少了算法

java 之 外觀模式大話設計模式

希望 重要 .com cad ima out 流程 mon nic 外觀設計模式,很多人都已經使用過,只是不知其名,一般一個很nice的系統,模塊化做的都很不錯,這樣如果新來一個業務,只需要把各個模塊組裝起來就可以滿足新的業務, 從程序的角度來說,就是我們只需要開一個類,

大話設計模式》讀後感

高效 風險 實踐 來看 存儲 復制 有助於 避免 叠代 轉載:http://blog.csdn.net/u013798619 第一次讀《大話設計模式》,是在剛接觸C#的時候。疲累於大部頭的官方教材中時,無意間翻開了這本生動有趣的書,甚是眼前一亮。由於當時C#基礎薄弱,只