设为首页 收藏本站
查看: 1953|回复: 0

[经验分享] 《大话设计模式》Python版代码实现

[复制链接]

尚未签到

发表于 2015-4-19 05:10:23 | 显示全部楼层 |阅读模式
  上一周把《大话设计模式》看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多、偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界。《大话设计模式》的代码使用C#写成的,而在本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式的理解,我在网上下载了一个C++版的源代码,并根据自己的理解边读这本书边动手实践C++源代码,同时将其改写成了Python代码,算是一箭三雕吧。
  由于这些代码的目的是展示各个设计模式而非完成一个具体的复杂任务,基于C++版本改写,例子的取材也和《大话设计模式》基本相同,再加上个人水平有限,因此这些Python版代码写的比较简单,虽然能跑起来是不假,不过难免有bug,而且实现也不一定最优,C++的味道比较浓而不够pythonic,还请高手包容指正。不过我还是尽量把或多或少有些pythonic的东西放在每个模式的“代码特点”部分进行展示,而这个“代码特点”里也不仅仅是pythonic的东西。
  使用Python版本为2.6。
  配图同样摘自《大话设计模式》,因此是C#风格的UML类图,为了便于排版已经缩小了。
  
  一、简单工厂模式
DSC0000.png
  模式特点:工厂根据条件产生不同功能的类。
  程序实例:四则运算计算器,根据用户的输入产生相应的运算类,用这个运算类处理具体的运算。
  代码特点:C/C++中的switch...case...分支使用字典的方式代替。
  使用异常机制对除数为0的情况进行处理。


DSC0001.gif DSC0002.gif 简单工厂模式


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()
  
  二、策略模式
DSC0003.png
  模式特点:定义算法家族并且分别封装,它们之间可以相互替换而不影响客户端。
  程序实例:商场收银软件,需要根据不同的销售策略方式进行收费
  代码特点:不同于同例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))
  三、装饰模式
DSC0004.png
  模式特点:动态地为对象增加额外的职责
  程序实例:展示一个人一件一件穿衣服的过程。
  代码特点:无


装饰模式


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()
  四、代理模式
DSC0005.png
  模式特点:为其他对象提供一种代理以控制对这个对象的访问。
  程序实例:同模式特点描述。
  代码特点:无


代理模式


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()
  五、工厂方法模式
DSC0006.png
  模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。
  程序实例:基类雷锋类,派生出学生类和志愿者类,由这两种子类完成“学雷锋”工作。子类的创建由雷锋工厂的对应的子类完成。
  代码特点:无


工厂方法模式


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()
  
  六、原型模式
DSC0007.png
  模式特点:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
  程序实例:从简历原型,生成新的简历
  代码特点:简历类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()
  七、模板方法模式
DSC0008.png
  模式特点:定义一个操作中的算法骨架,将一些步骤延迟至子类中。
  程序实例:考试时使用同一种考卷(父类),不同学生上交自己填写的试卷(子类方法的实现)
  代码特点:无


模板方法模式


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()
  
  八、外观模式
DSC0009.png
  模式特点:为一组调用提供一致的接口。
  程序实例:接口将几种调用分别组合成为两组,用户通过接口调用其中的一组。
  代码特点:无


外观模式


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()
  
  九、建造者模式
DSC00010.png
  模式特点:将一个复杂对象的构建(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()
  
  十、观察者模式
DSC00011.png
  模式特点:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者。
  程序实例:公司里有两种上班时趁老板不在时偷懒的员工:看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()
  十一、抽象工厂模式
DSC00012.png
  模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。
  程序实例:提供对不同的数据库访问的支持。
  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()
  十二、状态模式
   DSC00013.png
  
  模式特点:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
  程序实例:描述一个程序员的工作状态,当需要改变状态时发生改变,不同状态下的方法实现不同
  代码特点:无


状态模式


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

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-58428-1-1.html 上篇帖子: Python 入門語法和類型 下篇帖子: 从C#到Python —— 谈谈我学习Python一周来的体会
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表