1. 程式人生 > >《大話設計模式》Python版程式碼實現

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

一、簡單工廠模式

模式特點:工廠根據條件產生不同功能的類。

程式例項:四則運算計算器,根據使用者的輸入產生相應的運算類,用這個運算類處理具體的運算。

程式碼特點:C/C++中的switch...case...分支使用字典的方式代替。

     使用異常機制對除數為0的情況進行處理。

  1. class Operation(object):

  2. def get_result(self):

  3. pass

  4. class Add(Operation):

  5. def get_result(self):

  6. return self.op1+self.op2

  7. class Sub(Operation):

  8. def get_result(self):

  9. return self.op1 - self.op2

  10. class Mul(Operation):

  11. def get_result(self):

  12. return self.op1 * self.op2

  13. class Div(Operation):

  14. def get_result(self):

  15. return self.op1 / self.op2

  16. class Undef(Operation):

  17. def get_result(self):

  18. print "no define operator"

  19. class Factory(object):

  20. operator = dict()

  21. operator["+"] = Add()

  22. operator["-"] = Sub()

  23. operator["*"] = Mul()

  24. operator["/"] = Div()

  25. def create_operator(self, ch):

  26. op = self.operator[ch] if ch in self.operator else Undef()

  27. return op

  28. def main():

  29. print "*" * 30

  30. op = raw_input("operator:")

  31. opa = input("a:")

  32. opb = input("b:")

  33. factory = Factory()

  34. cal = factory.create_operator(op)

  35. cal.op1 = opa

  36. cal.op2 = opb

  37. print cal.get_result()

  38. if __name__ == "__main__":

  39. while 1:

  40. main()

  41. pass

二、策略模式

模式特點:定義演算法家族並且分別封裝,它們之間可以相互替換而不影響客戶端。

程式例項:商場收銀軟體,需要根據不同的銷售策略方式進行收費

程式碼特點:不同於同例1,這裡使用字典是為了避免關鍵字不在字典導致bug的陷阱。

  1. # _*_ coding:utf-8 _*_

  2. import os

  3. class CashSuper(object):

  4. def accept_cash(self, money):

  5. return 0

  6. class CashNormal(CashSuper):

  7. def accept_cash(self, money):

  8. return money

  9. class CashRebate(CashSuper):

  10. discount = 0

  11. def __init__(self, ds):

  12. self.discount = ds

  13. def accept_cash(self, money):

  14. return money * self.discount

  15. class CashReturn(CashSuper):

  16. total = 0

  17. ret = 0

  18. def __init__(self, total, ret):

  19. self.total = total

  20. self.ret = ret

  21. def accept_cash(self, money):

  22. if money >= self.total:

  23. return money - self.ret

  24. else:

  25. return money

  26. class CashContext:

  27. def __init__(self, child_class):

  28. self.cs = child_class

  29. def get_result(self, money):

  30. return self.cs.accept_cash(money)

  31. def main():

  32. print "*" * 30

  33. money = input("money:")

  34. strategy = dict()

  35. strategy[1] = CashContext(CashNormal())

  36. strategy[2] = CashContext(CashRebate(0.8))

  37. strategy[3] = CashContext(CashReturn(300, 100))

  38. ctype = input("type:[1]for normal,[2]for 80% discount [3]for 300 -100.")

  39. if ctype in strategy:

  40. cc = strategy[ctype]

  41. else:

  42. print "no define type. Use normal mode."

  43. cc = strategy[1]

  44. print "you will pay:%d" % (cc.GetResult(money))

  45. if __name__ == "__main__":

  46. main()

三、裝飾模式

模式特點:動態地為物件增加額外的職責

程式例項:展示一個人一件一件穿衣服的過程。

程式碼特點:無

  1. class Person(object):

  2. def __init__(self, name):

  3. self.name = name

  4. def show(self):

  5. print "dressed %s" % self.name

  6. class Finery(Person):

  7. component = None

  8. def __init__(self):

  9. super(Finery, self).__init__("")

  10. pass

  11. def decorate(self, ct):

  12. self.component = ct

  13. def show(self):

  14. if self.component is not None:

  15. self.component.show()

  16. class TShirts(Finery):

  17. def __init__(self):

  18. super(TShirts, self).__init__()

  19. pass

  20. def show(self):

  21. print "Big T-shirt "

  22. self.component.show()

  23. class BigTrouser(Finery):

  24. def __init__(self):

  25. super(BigTrouser, self).__init__()

  26. pass

  27. def show(self):

  28. print "Big Trouser "

  29. self.component.show()

  30. def main():

  31. p = Person("somebody")

  32. bt = BigTrouser()

  33. ts = TShirts()

  34. bt.decorate(p)

  35. ts.decorate(bt)

  36. ts.show()

  37. if __name__ == "__main__":

  38. main()

四、代理模式

模式特點:為其他物件提供一種代理以控制對這個物件的訪問。

程式例項:同模式特點描述。

程式碼特點:無

  1. class Interface(object):

  2. def request(self):

  3. return 0

  4. class RealSubject(Interface):

  5. def request(self):

  6. print "Real request."

  7. class Proxy(Interface):

  8. def request(self):

  9. self.real = RealSubject()

  10. self.real.request()

  11. def main():

  12. p = Proxy()

  13. p.request()

  14. if __name__ == "__main__":

  15. main()

五、工廠方法模式

模式特點:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。這使得一個類的例項化延遲到其子類。

程式例項:基類雷鋒類,派生出學生類和志願者類,由這兩種子類完成“學雷鋒”工作。子類的建立由雷鋒工廠的對應的子類完成。

程式碼特點:無

  1. class LeiFeng(object):

  2. def Sweep(self):

  3. print "LeiFeng sweep"

  4. class Student(LeiFeng):

  5. def Sweep(self):

  6. print "Student sweep"

  7. class Volenter(LeiFeng):

  8. def Sweep(self):

  9. print "Volenter sweep"

  10. class LeiFengFactory:

  11. def CreateLeiFeng(self):

  12. temp = LeiFeng()

  13. return temp

  14. class StudentFactory(LeiFengFactory):

  15. def CreateLeiFeng(self):

  16. temp = Student()

  17. return temp

  18. class VolenterFactory(LeiFengFactory):

  19. def CreateLeiFeng(self):

  20. temp = Volenter()

  21. return temp

  22. def main():

  23. sf = StudentFactory()

  24. s = sf.CreateLeiFeng()

  25. s.Sweep()

  26. sdf = VolenterFactory()

  27. sd = sdf.CreateLeiFeng()

  28. sd.Sweep()

  29. if __name__ == "__main__":

  30. main()

六、原型模式

模式特點:用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

程式例項:從簡歷原型,生成新的簡歷

程式碼特點:簡歷類Resume提供的Clone()方法其實並不是真正的Clone,只是為已存在物件增加了一次引用。

     Python為物件提供的copy模組中的copy方法和deepcopy方法已經實現了原型模式,但由於例子的層次較淺,二者看不出區別。

  1. import copy

  2. class WorkExp:

  3. place=""

  4. year=0

  5. class Resume:

  6. name = ''

  7. age = 0

  8. def __init__(self,n):

  9. self.name = n

  10. def SetAge(self,a):

  11. self.age = a

  12. def SetWorkExp(self,p,y):

  13. self.place = p

  14. self.year = y

  15. def Display(self):

  16. print self.age

  17. print self.place

  18. print self.year

  19. def Clone(self):

  20. #實際不是“克隆”,只是返回了自身

  21. return self

  22. def main():

  23. a = Resume("a")

  24. b = a.Clone()

  25. c = copy.copy(a)

  26. d = copy.deepcopy(a)

  27. a.SetAge(7)

  28. b.SetAge(12)

  29. c.SetAge(15)

  30. d.SetAge(18)

  31. a.SetWorkExp("PrimarySchool", 1996)

  32. b.SetWorkExp("MidSchool", 2001)

  33. c.SetWorkExp("HighSchool", 2004)

  34. d.SetWorkExp("University", 2007)

  35. a.Display()

  36. b.Display()

  37. c.Display()

  38. d.Display()

  39. if __name__ == "__main__":

  40. main()

七、模板方法模式

 

模式特點:定義一個操作中的演算法骨架,將一些步驟延遲至子類中。

程式例項:考試時使用同一種考卷(父類),不同學生上交自己填寫的試卷(子類方法的實現)

程式碼特點:無