作者:五岳 
出处:http://www.cnblogs.com/wuyuegb2312

上一周把《大话设计模式》看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多、偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界。《大话设计模式》的代码使用C#写成的,而在本人接触到的面向对象语言中,只对C++和Python还算了解,为了加深对各个模式的理解,我在网上下载了一个C++版的源代码,并根据自己的理解边读这本书边动手实践C++源代码,同时将其改写成了Python代码,算是一箭三雕吧。

  由于这些代码的目的是展示各个设计模式而非完成一个具体的复杂任务,基于C++版本改写,例子的取材也和《大话设计模式》基本相同,再加上个人水平有限,因此这些Python版代码写的比较简单,虽然能跑起来是不假,不过难免有bug,而且实现也不一定最优,C++的味道比较浓而不够pythonic,还请高手包容指正。不过我还是尽量把或多或少有些pythonic的东西放在每个模式的“代码特点”部分进行展示,而这个“代码特点”里也不仅仅是pythonic的东西。

  使用Python版本为2.6。

  配图同样摘自《大话设计模式》,因此是C#风格的UML类图,为了便于排版已经缩小了。

  

一、简单工厂模式

模式特点:工厂根据条件产生不同功能的类。

程序实例:四则运算计算器,根据用户的输入产生相应的运算类,用这个运算类处理具体的运算。

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

     使用异常机制对除数为0的情况进行处理。

 1 class Operation:
 2     def GetResult(self):
 3         pass
 4
 5 class OperationAdd(Operation):
 6     def GetResult(self):
 7         return self.op1+self.op2
 8
 9
10 class OperationSub(Operation):
11     def GetResult(self):
12         return self.op1-self.op2
13
14
15 class OperationMul(Operation):
16     def GetResult(self):
17         return self.op1*self.op2
18
19
20 class OperationDiv(Operation):
21     def GetResult(self):
22         try:
23             result = self.op1/self.op2
24             return result
25         except:
26             print "error:divided by zero."
27             return 0
28
29 class OperationUndef(Operation):
30     def GetResult(self):
31         print "Undefine operation."
32         return 0
33
34 class OperationFactory:
35     operation = {}
36     operation["+"] = OperationAdd();
37     operation["-"] = OperationSub();
38     operation["*"] = OperationMul();
39     operation["/"] = OperationDiv();
40     def createOperation(self,ch):
41         if ch in self.operation:
42             op = self.operation[ch]
43         else:
44             op = OperationUndef()
45         return op
46
47 if __name__ == "__main__":
48     op = raw_input("operator: ")
49     opa = input("a: ")
50     opb = input("b: ")
51     factory = OperationFactory()
52     cal = factory.createOperation(op)
53     cal.op1 = opa
54     cal.op2 = opb
55     print cal.GetResult()

View Code

二、策略模式

模式特点:定义算法家族并且分别封装,它们之间可以相互替换而不影响客户端。

程序实例:商场收银软件,需要根据不同的销售策略方式进行收费

代码特点:不同于同例1,这里使用字典是为了避免关键字不在字典导致bug的陷阱。

 1 class CashSuper:
 2     def AcceptCash(self,money):
 3         return 0
 4
 5 class CashNormal(CashSuper):
 6     def AcceptCash(self,money):
 7         return money
 8
 9 class CashRebate(CashSuper):
10     discount = 0
11     def __init__(self,ds):
12         self.discount = ds
13     def AcceptCash(self,money):
14         return money * self.discount
15
16 class CashReturn(CashSuper):
17     total = 0;
18     ret = 0;
19     def __init__(self,t,r):
20         self.total = t
21         self.ret = r
22     def AcceptCash(self,money):
23         if (money>=self.total):
24             return money - self.ret
25         else:
26             return money
27
28 class CashContext:
29     def __init__(self,csuper):
30         self.cs = csuper
31     def GetResult(self,money):
32         return self.cs.AcceptCash(money)
33
34 if __name__ == "__main__":
35     money = input("money:")
36     strategy = {}
37     strategy[1] = CashContext(CashNormal())
38     strategy[2] = CashContext(CashRebate(0.8))
39     strategy[3] = CashContext(CashReturn(300,100))
40     ctype = input("type:[1]for normal,[2]for 80% discount [3]for 300 -100.")
41     if ctype in strategy:
42         cc = strategy[ctype]
43     else:
44         print "Undefine type.Use normal mode."
45         cc = strategy[1]
46     print "you will pay:%d" %(cc.GetResult(money))

View Code

三、装饰模式

模式特点:动态地为对象增加额外的职责

程序实例:展示一个人一件一件穿衣服的过程。

代码特点:无

 1 class Person:
 2     def __init__(self,tname):
 3         self.name = tname
 4     def Show(self):
 5        print "dressed %s" %(self.name)
 6
 7 class Finery(Person):
 8     componet = None
 9     def __init__(self):
10         pass
11     def Decorate(self,ct):
12         self.componet = ct
13     def Show(self):
14     if(self.componet!=None):
15         self.componet.Show()
16
17 class TShirts(Finery):
18     def __init__(self):
19         pass
20     def Show(self):
21         print "Big T-shirt "
22         self.componet.Show()
23
24 class BigTrouser(Finery):
25     def __init__(self):
26         pass
27     def Show(self):
28         print "Big Trouser "
29         self.componet.Show()
30
31 if __name__ == "__main__":
32     p = Person("somebody")
33     bt = BigTrouser()
34     ts = TShirts()
35     bt.Decorate(p)
36     ts.Decorate(bt)
37     ts.Show()

View Code

四、代理模式

模式特点:为其他对象提供一种代理以控制对这个对象的访问。

程序实例:同模式特点描述。

代码特点:无

 1 class Interface :
 2     def Request(self):
 3     return 0
 4
 5 class RealSubject(Interface):
 6     def Request(self):
 7         print "Real request."
 8
 9 class Proxy(Interface):
10     def Request(self):
11         self.real = RealSubject()
12         self.real.Request()
13
14 if __name__ == "__main__":
15     p = Proxy()
16     p.Request()

View Code

五、工厂方法模式

模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。

程序实例:基类雷锋类,派生出学生类和志愿者类,由这两种子类完成“学雷锋”工作。子类的创建由雷锋工厂的对应的子类完成。

代码特点:无

 1 class LeiFeng:
 2     def Sweep(self):
 3         print "LeiFeng sweep"
 4
 5 class Student(LeiFeng):
 6     def Sweep(self):
 7         print "Student sweep"
 8
 9 class Volenter(LeiFeng):
10     def Sweep(self):
11         print "Volenter sweep"
12
13 class LeiFengFactory:
14     def CreateLeiFeng(self):
15         temp = LeiFeng()
16         return temp
17
18 class StudentFactory(LeiFengFactory):
19     def CreateLeiFeng(self):
20         temp = Student()
21         return temp
22
23 class VolenterFactory(LeiFengFactory):
24     def CreateLeiFeng(self):
25         temp = Volenter()
26         return temp
27
28 if __name__ == "__main__":
29     sf = StudentFactory()
30     s=sf.CreateLeiFeng()
31     s.Sweep()
32     sdf = VolenterFactory()
33     sd=sdf.CreateLeiFeng()
34     sd.Sweep()

View Code

六、原型模式

模式特点:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

程序实例:从简历原型,生成新的简历

代码特点:简历类Resume提供的Clone()方法其实并不是真正的Clone,只是为已存在对象增加了一次引用。

     Python为对象提供的copy模块中的copy方法和deepcopy方法已经实现了原型模式,但由于例子的层次较浅,二者看不出区别。

 1 import copy
 2 class WorkExp:
 3     place=""
 4     year=0
 5
 6 class Resume:
 7     name = ''
 8     age = 0
 9     def __init__(self,n):
10         self.name = n
11     def SetAge(self,a):
12         self.age = a
13     def SetWorkExp(self,p,y):
14         self.place = p
15         self.year = y
16     def Display(self):
17         print self.age
18         print self.place
19         print self.year
20     def Clone(self):
21     #实际不是“克隆”,只是返回了自身
22         return self
23
24 if __name__ == "__main__":
25     a = Resume("a")
26     b = a.Clone()
27     c = copy.copy(a)
28     d = copy.deepcopy(a)
29     a.SetAge(7)
30     b.SetAge(12)
31     c.SetAge(15)
32     d.SetAge(18)
33     a.SetWorkExp("PrimarySchool",1996)
34     b.SetWorkExp("MidSchool",2001)
35     c.SetWorkExp("HighSchool",2004)
36     d.SetWorkExp("University",2007)
37     a.Display()
38     b.Display()
39     c.Display()
40     d.Display()

View Code

七、模板方法模式

模式特点:定义一个操作中的算法骨架,将一些步骤延迟至子类中。

程序实例:考试时使用同一种考卷(父类),不同学生上交自己填写的试卷(子类方法的实现)

代码特点:无

 1 class TestPaper:
 2     def TestQuestion1(self):
 3         print "Test1:A. B. C. D."
 4         print "(%s)" %self.Answer1()
 5
 6     def TestQuestion2(self):
 7         print "Test1:A. B. C. D."
 8         print "(%s)" %self.Answer2()
 9     def Answer1(self):
10         return ""
11     def Answer2(self):
12         return ""
13
14 class TestPaperA(TestPaper):
15     def Answer1(self):
16         return "B"
17     def Answer2(self):
18         return "C";
19
20 class TestPaperB(TestPaper):
21     def Answer1(self):
22         return "D"
23     def Answer2(self):
24         return "D";
25
26 if __name__ == "__main__":
27     s1 = TestPaperA()
28     s2 = TestPaperB()
29     print "student 1"
30     s1.TestQuestion1()
31     s1.TestQuestion2()
32     print "student 2"
33     s2.TestQuestion1()
34     s2.TestQuestion2()

View Code

八、外观模式

模式特点:为一组调用提供一致的接口。

程序实例:接口将几种调用分别组合成为两组,用户通过接口调用其中的一组。

代码特点:无

 1 class SubSystemOne:
 2     def MethodOne(self):
 3         print "SubSysOne"
 4
 5 class SubSystemTwo:
 6     def MethodTwo(self):
 7         print "SubSysTwo"
 8
 9 class SubSystemThree:
10     def MethodThree(self):
11         print "SubSysThree"
12
13 class SubSystemFour:
14     def MethodFour(self):
15         print "SubSysFour"
16
17
18 class Facade:
19     def __init__(self):
20         self.one = SubSystemOne()
21         self.two = SubSystemTwo()
22         self.three = SubSystemThree()
23         self.four = SubSystemFour()
24     def MethodA(self):
25         print "MethodA"
26         self.one.MethodOne()
27         self.two.MethodTwo()
28         self.four.MethodFour()
29     def MethodB(self):
30         print "MethodB"
31         self.two.MethodTwo()
32         self.three.MethodThree()
33
34 if __name__ == "__main__":
35     facade = Facade()
36     facade.MethodA()
37     facade.MethodB()

View Code

九、建造者模式

模式特点:将一个复杂对象的构建(Director)与它的表示(Builder)分离,使得同样的构建过程可以创建不同的表示(ConcreteBuilder)。

程序实例:“画”出一个四肢健全(头身手腿)的小人

代码特点:无

 1 class Person:
 2     def CreateHead(self):
 3         pass
 4     def CreateHand(self):
 5         pass
 6     def CreateBody(self):
 7         pass
 8     def CreateFoot(self):
 9         pass
10
11 class ThinPerson(Person):
12     def CreateHead(self):
13         print "thin head"
14     def CreateHand(self):
15         print "thin hand"
16     def CreateBody(self):
17         print "thin body"
18     def CreateFoot(self):
19         print "thin foot"
20
21 class ThickPerson(Person):
22     def CreateHead(self):
23         print "thick head"
24     def CreateHand(self):
25         print "thick hand"
26     def CreateBody(self):
27         print "thick body"
28     def CreateFoot(self):
29         print "thick foot"
30
31 class Director:
32     def __init__(self,temp):
33         self.p = temp
34     def Create(self):
35         self.p.CreateHead()
36         self.p.CreateBody()
37         self.p.CreateHand()
38         self.p.CreateFoot()
39
40 if __name__ == "__main__":
41     p = ThickPerson()
42     d = Director(p)
43     d.Create()

View Code

十、观察者模式

模式特点:定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者。

程序实例:公司里有两种上班时趁老板不在时偷懒的员工:看NBA的和看股票行情的,并且事先让老板秘书当老板出现时通知他们继续做手头上的工作。

程序特点:无

 1 class Observer:
 2     def __init__(self,strname,strsub):
 3         self.name = strname
 4         self.sub = strsub
 5     def Update(self):
 6         pass
 7
 8 class StockObserver(Observer):
 9     #no need to rewrite __init__()
10     def Update(self):
11         print "%s:%s,stop watching Stock and go on work!" %(self.name,self.sub.action)
12
13 class NBAObserver(Observer):
14     def Update(self):
15         print "%s:%s,stop watching NBA and go on work!" %(self.name,self.sub.action)
16
17 class SecretaryBase:
18     def __init__(self):
19         self.observers = []
20     def Attach(self,new_observer):
21         pass
22     def Notify(self):
23         pass
24
25 class Secretary(SecretaryBase):
26     def Attach(self,new_observer):
27         self.observers.append(new_observer)
28     def Notify(self):
29         for p in self.observers:
30             p.Update()
31
32 if __name__ == "__main__":
33     p = Secretary()
34     s1 = StockObserver("xh",p)
35     s2 = NBAObserver("wyt",p)
36     p.Attach(s1);
37     p.Attach(s2);
38     p.action = "WARNING:BOSS ";
39     p.Notify()

View Code

十一、抽象工厂模式

模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们的类。

程序实例:提供对不同的数据库访问的支持。

     IUser和IDepartment是两种不同的抽象产品,它们都有Access和SQL Server这两种不同的实现;IFactory是产生IUser和IDepartment的抽象工厂,根据具体实现(AccessFactory和SqlFactory)产生对应的具体的对象(CAccessUser与CAccessDepartment,或者CSqlUser与CSqlDepartment)。

代码特点:无

 1 class IUser:
 2     def GetUser(self):
 3         pass
 4     def InsertUser(self):
 5         pass
 6
 7 class IDepartment:
 8     def GetDepartment(self):
 9         pass
10     def InsertDepartment(self):
11         pass
12
13 class CAccessUser(IUser):
14     def GetUser(self):
15         print "Access GetUser"
16     def InsertUser(self):
17         print "Access InsertUser"
18
19
20 class CAccessDepartment(IDepartment):
21     def GetDepartment(self):
22         print "Access GetDepartment"
23     def InsertDepartment(self):
24         print "Access InsertDepartment"
25
26 class CSqlUser(IUser):
27     def GetUser(self):
28         print "Sql GetUser"
29     def InsertUser(self):
30         print "Sql InsertUser"
31
32
33 class CSqlDepartment(IDepartment):
34     def GetDepartment(self):
35         print "Sql GetDepartment"
36     def InsertDepartment(self):
37         print "Sql InsertDepartment"
38
39 class IFactory:
40     def CreateUser(self):
41         pass
42     def CreateDepartment(self):
43         pass
44
45 class AccessFactory(IFactory):
46     def CreateUser(self):
47         temp=CAccessUser()
48         return temp
49     def CreateDepartment(self):
50         temp = CAccessDepartment()
51         return temp
52
53 class SqlFactory(IFactory):
54     def CreateUser(self):
55         temp = CSqlUser()
56         return temp
57     def CreateDepartment(self):
58         temp = CSqlDepartment()
59         return temp
60
61 if __name__ == "__main__":
62     factory = SqlFactory()
63     user=factory.CreateUser()
64     depart=factory.CreateDepartment()
65     user.GetUser()
66     depart.GetDepartment()

View Code

十二、状态模式

模式特点:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。

程序实例:描述一个程序员的工作状态,当需要改变状态时发生改变,不同状态下的方法实现不同

代码特点:无

 1 class State:
 2     def WirteProgram(self):
 3         pass
 4
 5 class Work:
 6     def __init__(self):
 7         self.hour = 9
 8         self.current = ForenoonState()
 9     def SetState(self,temp):
10         self.current = temp
11     def WriteProgram(self):
12         self.current.WriteProgram(self)
13
14 class NoonState(State):
15     def WriteProgram(self,w):
16         print "noon working"
17         if (w.hour<13):
18             print "fun."
19         else:
20             print "need to rest."
21
22 class ForenoonState(State):
23     def WriteProgram(self,w):
24         if (w.hour<12):
25             print "morning working"
26             print "energetic"
27         else:
28             w.SetState(NoonState())
29             w.WriteProgram()
30
31 if __name__ == "__main__":
32     mywork = Work()
33     mywork.hour = 9
34     mywork.WriteProgram()
35     mywork.hour =14
36     mywork.WriteProgram()

View Code

十三、适配器模式

模式特点:将一个类的接口转换成为客户希望的另外一个接口。

程序实例:用户通过适配器使用一个类的方法。

代码特点:无

 1 class Target:
 2     def Request():
 3         print "common request."
 4
 5 class Adaptee(Target):
 6     def SpecificRequest(self):
 7         print "specific request."
 8
 9 class Adapter(Target):
10     def __init__(self,ada):
11         self.adaptee = ada
12     def Request(self):
13         self.adaptee.SpecificRequest()
14
15 if __name__ == "__main__":
16     adaptee = Adaptee()
17     adapter = Adapter(adaptee)
18     adapter.Request()

View Code

十四、备忘录模式

模式特点:在不破坏封装性的前提下捕获一个对象的内部状态,并在该对象之外保存这个状态,以后可以将对象恢复到这个状态。

程序实例:将Originator对象的状态封装成Memo对象保存在Caretaker内

代码特点:无

 1 class Originator:
 2     def __init__(self):
 3         self.state = ""
 4     def Show(self):
 5         print self.state
 6     def CreateMemo(self):
 7         return Memo(self.state)
 8     def SetMemo(self,memo):
 9         self.state = memo.state
10
11 class Memo:
12     state= ""
13     def __init__(self,ts):
14         self.state = ts
15
16 class Caretaker:
17     memo = ""
18
19 if __name__ == "__main__":
20     on = Originator()
21     on.state = "on"
22     on.Show()
23     c = Caretaker()
24     c.memo=on.CreateMemo()
25     on.state="off"
26     on.Show()
27     on.SetMemo(c.memo)
28     on.Show()

View Code

十五、组合模式

模式特点:将对象组合成成树形结构以表示“部分-整体”的层次结构

程序实例:公司人员的组织结构

代码特点:无

 1 class Component:
 2     def __init__(self,strName):
 3         self.m_strName = strName
 4     def Add(self,com):
 5         pass
 6     def Display(self,nDepth):
 7         pass
 8
 9 class Leaf(Component):
10     def Add(self,com):
11         print "leaf can't add"
12     def Display(self,nDepth):
13         strtemp = ""
14         for i in range(nDepth):
15             strtemp=strtemp+"-"
16         strtemp=strtemp+self.m_strName
17         print strtemp
18
19 class Composite(Component):
20     def __init__(self,strName):
21         self.m_strName = strName
22         self.c = []
23     def Add(self,com):
24         self.c.append(com)
25     def Display(self,nDepth):
26         strtemp=""
27         for i in range(nDepth):
28             strtemp=strtemp+"-"
29         strtemp=strtemp+self.m_strName
30         print strtemp
31         for com in self.c:
32             com.Display(nDepth+2)
33
34 if __name__ == "__main__":
35     p = Composite("Wong")
36     p.Add(Leaf("Lee"))
37     p.Add(Leaf("Zhao"))
38     p1 = Composite("Wu")
39     p1.Add(Leaf("San"))
40     p.Add(p1)
41     p.Display(1);

View Code

十六、迭代器模式

模式特点:提供方法顺序访问一个聚合对象中各元素,而又不暴露该对象的内部表示

说明:这个模式没有写代码实现,原因是使用Python的列表和for ... in list就能够完成不同类型对象聚合的迭代功能了。

十七、单例模式

模式特点:保证类仅有一个实例,并提供一个访问它的全局访问点。

说明:     为了实现单例模式费了不少工夫,后来查到一篇博文对此有很详细的介绍,而且实现方式也很丰富,通过对代码的学习可以了解更多Python的用法。以下的代码出自GhostFromHeaven的专栏,地址:http://blog.csdn.net/ghostfromheaven/article/details/7671853。不过正如其作者在Python单例模式终极版所说:

我要问的是,Python真的需要单例模式吗?我指像其他编程语言中的单例模式。

答案是:不需要!

因为,Python有模块(module),最pythonic的单例典范。

模块在在一个应用程序中只有一份,它本身就是单例的,将你所需要的属性和方法,直接暴露在模块中变成模块的全局变量和方法即可!

  1 #-*- encoding=utf-8 -*-
  2 print '----------------------方法1--------------------------'
  3 #方法1,实现__new__方法
  4 #并在将一个类的实例绑定到类变量_instance上,
  5 #如果cls._instance为None说明该类还没有实例化过,实例化该类,并返回
  6 #如果cls._instance不为None,直接返回cls._instance
  7 class Singleton(object):
  8     def __new__(cls, *args, **kw):
  9         if not hasattr(cls, '_instance'):
 10             orig = super(Singleton, cls)
 11             cls._instance = orig.__new__(cls, *args, **kw)
 12         return cls._instance
 13
 14 class MyClass(Singleton):
 15     a = 1
 16
 17 one = MyClass()
 18 two = MyClass()
 19
 20 two.a = 3
 21 print one.a
 22 #3
 23 #one和two完全相同,可以用id(), ==, is检测
 24 print id(one)
 25 #29097904
 26 print id(two)
 27 #29097904
 28 print one == two
 29 #True
 30 print one is two
 31 #True
 32
 33 print '----------------------方法2--------------------------'
 34 #方法2,共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
 35 #同一个类的所有实例天然拥有相同的行为(方法),
 36 #只需要保证同一个类的所有实例具有相同的状态(属性)即可
 37 #所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
 38 #可参看:http://code.activestate.com/recipes/66531/
 39 class Borg(object):
 40     _state = {}
 41     def __new__(cls, *args, **kw):
 42         ob = super(Borg, cls).__new__(cls, *args, **kw)
 43         ob.__dict__ = cls._state
 44         return ob
 45
 46 class MyClass2(Borg):
 47     a = 1
 48
 49 one = MyClass2()
 50 two = MyClass2()
 51
 52 #one和two是两个不同的对象,id, ==, is对比结果可看出
 53 two.a = 3
 54 print one.a
 55 #3
 56 print id(one)
 57 #28873680
 58 print id(two)
 59 #28873712
 60 print one == two
 61 #False
 62 print one is two
 63 #False
 64 #但是one和two具有相同的(同一个__dict__属性),见:
 65 print id(one.__dict__)
 66 #30104000
 67 print id(two.__dict__)
 68 #30104000
 69
 70 print '----------------------方法3--------------------------'
 71 #方法3:本质上是方法1的升级(或者说高级)版
 72 #使用__metaclass__(元类)的高级python用法
 73 class Singleton2(type):
 74     def __init__(cls, name, bases, dict):
 75         super(Singleton2, cls).__init__(name, bases, dict)
 76         cls._instance = None
 77     def __call__(cls, *args, **kw):
 78         if cls._instance is None:
 79             cls._instance = super(Singleton2, cls).__call__(*args, **kw)
 80         return cls._instance
 81
 82 class MyClass3(object):
 83     __metaclass__ = Singleton2
 84
 85 one = MyClass3()
 86 two = MyClass3()
 87
 88 two.a = 3
 89 print one.a
 90 #3
 91 print id(one)
 92 #31495472
 93 print id(two)
 94 #31495472
 95 print one == two
 96 #True
 97 print one is two
 98 #True
 99
100 print '----------------------方法4--------------------------'
101 #方法4:也是方法1的升级(高级)版本,
102 #使用装饰器(decorator),
103 #这是一种更pythonic,更elegant的方法,
104 #单例类本身根本不知道自己是单例的,因为他本身(自己的代码)并不是单例的
105 def singleton(cls, *args, **kw):
106     instances = {}
107     def _singleton():
108         if cls not in instances:
109             instances[cls] = cls(*args, **kw)
110         return instances[cls]
111     return _singleton
112
113 @singleton
114 class MyClass4(object):
115     a = 1
116     def __init__(self, x=0):
117         self.x = x
118
119 one = MyClass4()
120 two = MyClass4()
121
122 two.a = 3
123 print one.a
124 #3
125 print id(one)
126 #29660784
127 print id(two)
128 #29660784
129 print one == two
130 #True
131 print one is two
132 #True
133 one.x = 1
134 print one.x
135 #1
136 print two.x
137 #1

View Code

十八、桥接模式

模式特点:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

程序实例:两种品牌的手机,要求它们都可以运行游戏和通讯录两个软件,而不是为每个品牌的手机都独立编写不同的软件。

代码特点:虽然使用了object的新型类,不过在这里不是必须的,是对在Python2.2之后“尽量使用新型类”的建议的遵从示范。

 1 class HandsetSoft(object):
 2     def Run(self):
 3         pass
 4
 5 class HandsetGame(HandsetSoft):
 6     def Run(self):
 7         print "Game"
 8
 9 class HandsetAddressList(HandsetSoft):
10     def Run(self):
11         print "Address List"
12
13 class HandsetBrand(object):
14     def __init__(self):
15         self.m_soft = None
16     def SetHandsetSoft(self,temp):
17         self.m_soft= temp
18     def Run(self):
19         pass
20
21 class HandsetBrandM(HandsetBrand):
22     def Run(self):
23         if not (self.m_soft == None):
24             print "BrandM"
25             self.m_soft.Run()
26
27 class HandsetBrandN(HandsetBrand):
28     def Run(self):
29         if not (self.m_soft == None):
30             print "BrandN"
31             self.m_soft.Run()
32
33 if __name__ == "__main__":
34     brand = HandsetBrandM()
35     brand.SetHandsetSoft(HandsetGame())
36     brand.Run()
37     brand.SetHandsetSoft(HandsetAddressList())
38     brand.Run()   

View Code

十九、命令模式

模式特点:将请求封装成对象,从而使可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。

程序实例:烧烤店有两种食物,羊肉串和鸡翅。客户向服务员点单,服务员将点好的单告诉大厨,由大厨进行烹饪。

代码特点:注意在遍历列表时不要用注释的方式删除,否则会出现bug。bug示例程序附在后面,我认为这是因为remove打乱了for迭代查询列表的顺序导致的。

 1 class Barbucer:
 2     def MakeMutton(self):
 3         print "Mutton"
 4     def MakeChickenWing(self):
 5         print "Chicken Wing"
 6
 7 class Command:
 8     def __init__(self,temp):
 9         self.receiver=temp
10     def ExecuteCmd(self):
11         pass
12
13 class BakeMuttonCmd(Command):
14     def ExecuteCmd(self):
15         self.receiver.MakeMutton()
16
17 class ChickenWingCmd(Command):
18     def ExecuteCmd(self):
19         self.receiver.MakeChickenWing()
20
21 class Waiter:
22     def __init__(self):
23         self.order =[]
24     def SetCmd(self,command):
25         self.order.append(command)
26         print "Add Order"
27     def Notify(self):
28         for cmd in self.order:
29             #self.order.remove(cmd)
30             #lead to a bug
31             cmd.ExecuteCmd()
32
33
34 if __name__ == "__main__":
35     barbucer=Barbucer()
36     cmd=BakeMuttonCmd(barbucer)
37     cmd2=ChickenWingCmd(barbucer)
38     girl=Waiter()
39     girl.SetCmd(cmd)
40     girl.SetCmd(cmd2)
41     girl.Notify()

View Code

在for中remove会导致bug的展示代码:

c=[0,1,2,3]
for i in c:print ic.remove(i)#output:
#0
#2

View Code

二十、职责链模式

模式特点:使多个对象都有机会处理请求,从而避免发送者和接收者的耦合关系。将对象连成链并沿着这条链传递请求直到被处理。

程序实例:请假和加薪等请求发给上级,如果上级无权决定,那么递交给上级的上级。

代码特点:无

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)

View Code

二十一、中介者模式

模式特点:用一个对象来封装一系列的对象交互,中介者使各对象不需要显示地相互引用,从而使耦合松散,而且可以独立地改变它们之间的交互。

程序实例:两个对象通过中介者相互通信

代码特点:无

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.");

View Code

二十二、享元模式

模式特点:运用共享技术有效地支持大量细粒度的对象。

程序实例:一个网站工厂,根据用户请求的类别返回相应类别的网站。如果这种类别的网站已经在服务器上,那么返回这种网站并加上不同用户的独特的数据;如果没有,那么生成一个。

代码特点:为了展示每种网站的由用户请求的次数,这里为它们建立了一个引用次数的字典。

      之所以不用Python的sys模块中的sys.getrefcount()方法统计引用计数是因为有的对象可能在别处被隐式的引用,从而增加了引用计数。

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()

View Code

二十三、解释器模式

模式特点:给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子。

程序实例:(只是模式特点的最简单示范)

代码特点:无

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)

View Code

二十四、访问者模式

模式特点:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

程序实例:对于男人和女人(接受访问者的元素,ObjectStructure用于穷举这些元素),不同的遭遇(具体的访问者)引发两种对象的不同行为。

代码特点:无

 1 # -*- coding: UTF-8 -*-
 2 class Person:
 3     def Accept(self,visitor):
 4         pass
 5
 6 class Man(Person):
 7     def Accept(self,visitor):
 8         visitor.GetManConclusion(self)
 9
10 class Woman(Person):
11     def Accept(self,visitor):
12         visitor.GetWomanConclusion(self)
13
14 class Action:
15     def GetManConclusion(self,concreteElementA):
16         pass
17     def GetWomanConclusion(self,concreteElementB):
18         pass
19
20 class Success(Action):
21     def GetManConclusion(self,concreteElementA):
22         print "男人成功时,背后有个伟大的女人"
23     def GetWomanConclusion(self,concreteElementB):
24         print "女人成功时,背后有个不成功的男人"
25
26 class Failure(Action):
27     def GetManConclusion(self,concreteElementA):
28         print "男人失败时,闷头喝酒,谁也不用劝"
29     def GetWomanConclusion(self,concreteElementB):
30         print "女人失败时,眼泪汪汪,谁也劝不了"
31
32
33 class ObjectStructure:
34     def __init__(self):
35         self.plist=[]
36     def Add(self,p):
37         self.plist=self.plist+[p]
38     def Display(self,act):
39         for p in self.plist:
40             p.Accept(act)
41
42 if __name__ == "__main__":
43     os = ObjectStructure()
44     os.Add(Man())
45     os.Add(Woman())
46     sc = Success()
47     os.Display(sc)
48     fl = Failure()
49     os.Display(fl)

View Code

转载于:https://www.cnblogs.com/kefeiGame/p/8065268.html

大话设计模式--Python相关推荐

  1. 大话设计模式Python实现-简单工厂模式

    简单工厂模式(Simple Factory Pattern):是通过专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类. 下面使用简单工厂模式实现一个简单的四则运算 1 #!/us ...

  2. 大话设计模式Python实现-观察者模式

    观察者模式(发布-订阅模式 Publish Subscribe Pattern):定义了一种一对多的关系,让多个观察对象同时监听一个主题对象,当主题对象状态发生变化时会通知所有观察者,是它们能够自动更 ...

  3. 【Python】《大话设计模式》Python版代码实现

    <大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...

  4. 大话设计模式之装饰模式(python实现)

    大话设计模式之装饰模式 使用场景 定义 装饰模式结构图 python实现装饰模式 代码结构图 优点 使用场景 建造过程不稳定,不确定.把所需的功能按照正确的顺序串联起来进行控制. 新加入的东西仅仅是为 ...

  5. python大话设计模式

    上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼界.<大话设计模式>的代码使用C#写成的 ...

  6. 《大话设计模式》Python版代码实现

    <大话设计模式>Python版代码实现 上一周把<大话设计模式>看完了,对面向对象技术有了新的理解,对于一个在C下写代码比较多.偶尔会用到一些脚本语言写脚本的人来说,很是开阔眼 ...

  7. 《大话设计模式》读书总结

    2019独角兽企业重金招聘Python工程师标准>>> 大三上学期(2010年下半年),软件工程专业开设了 设计模式这门B类课.当时,没有买学校的,4人帮写的那本经典的设计模式书籍. ...

  8. 《大话设计模式(C#实现)》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+设计模式+GoF+UML+单例模式+观察者模式+抽象工厂+代理模式+框架编程+立钻哥哥++OK+)

    <大话设计模式(C#实现)> 版本 作者 参与者 完成日期 备注 YanlzFramework_GoF_V01_1.0 严立钻 2020.02.10 ##<大话设计模式(C#实现)& ...

  9. 【大话设计模式】——浅谈设计模式基础

    初学设计模式给我最大的感受是:人类真是伟大啊!单单是设计模式的基础课程就让我感受到了强烈的生活气息. 个人感觉<大话设计模式>这本书写的真好.让貌似非常晦涩难懂的设计模式变的生活化.趣味化 ...

最新文章

  1. script中用php
  2. IOS开发笔记15-自定义类
  3. BitmapFactory: inSampleSize 的一些思考
  4. python编码与存储读取数据(数组字典)
  5. 3d 室内地图_微软科研人员欲通过3D点云混淆技术保护AR定位隐私
  6. python实例26[计算MD5]
  7. 使用 matlab 进行正太拟合
  8. use proxy for git
  9. Spring boot mqtt客户端
  10. ansible远程在Windows server 2012 R2 安装vcredist(2008 2010 2012 2013)
  11. RestTemplate获取HTTP状态码
  12. 【Scrum】借由数个冲刺,实现产品的敏捷开发!
  13. 会动的小狗纯HTML代码
  14. 符号_王者荣耀2019名字特殊符号大全 最好看的特殊符号复制
  15. Altium Desinger 20概述-安装及卸载
  16. 身家200亿到入狱,中国股神的悲壮人生
  17. 李永乐六套卷-2021
  18. WIFI密码破解全攻略
  19. 信贷产品额度定价场景下的回归模型效果评估
  20. 计算机中z代表啥子意思,cpuz是什么怎么使用

热门文章

  1. 大一到大四的超级实用网站(转载)
  2. ⑤早起的鸟儿有虫吃-JSTL核心标签库[收藏]
  3. 5G时代加速到来,边缘计算何时取代“核心”计算?
  4. Latex基本表格绘制
  5. 不乱于心,不困于情。不畏将来,不念过往
  6. 转发器-集线器-适配器-网桥-交换机-路由器-网关
  7. 以史为鉴,编程语言,启示录之系统觉醒
  8. 可口可乐从此彻底废除“首席营销官”,设立“首席增长官”
  9. QQ会员服务介绍:存储类增值服务(转)
  10. 独孤九剑与乾坤大挪移—uikiller插件系统