《大話設計模式》Python版程式碼實現
一、簡單工廠模式
模式特點:工廠根據條件產生不同功能的類。
程式例項:四則運算計算器,根據使用者的輸入產生相應的運算類,用這個運算類處理具體的運算。
程式碼特點:C/C++中的switch...case...分支使用字典的方式代替。
使用異常機制對除數為0的情況進行處理。
-
class Operation(object):
-
def get_result(self):
-
pass
-
class Add(Operation):
-
def get_result(self):
-
return self.op1+self.op2
-
class Sub(Operation):
-
def get_result(self):
-
return self.op1 - self.op2
-
class Mul(Operation):
-
def get_result(self):
-
return self.op1 * self.op2
-
class Div(Operation):
-
def get_result(self):
-
return self.op1 / self.op2
-
class Undef(Operation):
-
def get_result(self):
-
print "no define operator"
-
class Factory(object):
-
operator = dict()
-
operator["+"] = Add()
-
operator["-"] = Sub()
-
operator["*"] = Mul()
-
operator["/"] = Div()
-
def create_operator(self, ch):
-
op = self.operator[ch] if ch in self.operator else Undef()
-
return op
-
def main():
-
print "*" * 30
-
op = raw_input("operator:")
-
opa = input("a:")
-
opb = input("b:")
-
factory = Factory()
-
cal = factory.create_operator(op)
-
cal.op1 = opa
-
cal.op2 = opb
-
print cal.get_result()
-
if __name__ == "__main__":
-
while 1:
-
main()
-
pass
二、策略模式
模式特點:定義演算法家族並且分別封裝,它們之間可以相互替換而不影響客戶端。
程式例項:商場收銀軟體,需要根據不同的銷售策略方式進行收費
程式碼特點:不同於同例1,這裡使用字典是為了避免關鍵字不在字典導致bug的陷阱。
-
# _*_ coding:utf-8 _*_
-
import os
-
class CashSuper(object):
-
def accept_cash(self, money):
-
return 0
-
class CashNormal(CashSuper):
-
def accept_cash(self, money):
-
return money
-
class CashRebate(CashSuper):
-
discount = 0
-
def __init__(self, ds):
-
self.discount = ds
-
def accept_cash(self, money):
-
return money * self.discount
-
class CashReturn(CashSuper):
-
total = 0
-
ret = 0
-
def __init__(self, total, ret):
-
self.total = total
-
self.ret = ret
-
def accept_cash(self, money):
-
if money >= self.total:
-
return money - self.ret
-
else:
-
return money
-
class CashContext:
-
def __init__(self, child_class):
-
self.cs = child_class
-
def get_result(self, money):
-
return self.cs.accept_cash(money)
-
def main():
-
print "*" * 30
-
money = input("money:")
-
strategy = dict()
-
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 "no define type. Use normal mode."
-
cc = strategy[1]
-
print "you will pay:%d" % (cc.GetResult(money))
-
if __name__ == "__main__":
-
main()
三、裝飾模式
模式特點:動態地為物件增加額外的職責
程式例項:展示一個人一件一件穿衣服的過程。
程式碼特點:無
-
class Person(object):
-
def __init__(self, name):
-
self.name = name
-
def show(self):
-
print "dressed %s" % self.name
-
class Finery(Person):
-
component = None
-
def __init__(self):
-
super(Finery, self).__init__("")
-
pass
-
def decorate(self, ct):
-
self.component = ct
-
def show(self):
-
if self.component is not None:
-
self.component.show()
-
class TShirts(Finery):
-
def __init__(self):
-
super(TShirts, self).__init__()
-
pass
-
def show(self):
-
print "Big T-shirt "
-
self.component.show()
-
class BigTrouser(Finery):
-
def __init__(self):
-
super(BigTrouser, self).__init__()
-
pass
-
def 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()
四、代理模式
模式特點:為其他物件提供一種代理以控制對這個物件的訪問。
程式例項:同模式特點描述。
程式碼特點:無
-
class Interface(object):
-
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()
-
def main():
-
p = Proxy()
-
p.request()
-
if __name__ == "__main__":
-
main()
五、工廠方法模式
模式特點:定義一個用於建立物件的介面,讓子類決定例項化哪一個類。這使得一個類的例項化延遲到其子類。
程式例項:基類雷鋒類,派生出學生類和志願者類,由這兩種子類完成“學雷鋒”工作。子類的建立由雷鋒工廠的對應的子類完成。
程式碼特點:無
-
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 temp
-
class StudentFactory(LeiFengFactory):
-
def CreateLeiFeng(self):
-
temp = Student()
-
return temp
-
class VolenterFactory(LeiFengFactory):
-
def CreateLeiFeng(self):
-
temp = Volenter()
-
return temp
-
def main():
-
sf = StudentFactory()
-
s = sf.CreateLeiFeng()
-
s.Sweep()
-
sdf = VolenterFactory()
-
sd = sdf.CreateLeiFeng()
-
sd.Sweep()
-
if __name__ == "__main__":
-
main()
六、原型模式
模式特點:用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。
程式例項:從簡歷原型,生成新的簡歷
程式碼特點:簡歷類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
-
def 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()
七、模板方法模式
模式特點:定義一個操作中的演算法骨架,將一些步驟延遲至子類中。
程式例項:考試時使用同一種考卷(父類),不同學生上交自己填寫的試卷(子類方法的實現)
程式碼特點:無