设计模式之创造型模式(抽象工厂模式、建造者模式、工厂模式、原型模式、单例模式)

--------------------------------- 创建型模式 --------------------------------
- 隐藏了这些类的实例是如何被创建和放在一起,整个系统关于这些对象所直到的  -
- 由抽象类所定义的接口。这样,创建型模式在创建了什么、谁创建它、它是怎么  -
- 被创建的,以及何时创建这些方面提供了很大的灵活性。                               -
-----------------------------------------------------------------------------
1. 抽象工厂模式

提供一个创建一系列或相关依赖对象的接口,而无需制定它们具体的类。

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 '''
 4 抽象工厂模式
 5 模式特点:提供一个创建一系列相关或相互依赖对象的接口,而无需知道能够它们具体的类。
 6 程序实例:提供对不同的数据库访问的支持。
 7 代码特点:无
 8 注:'I'开头的类是接口,需要子类去实现,此命名方法为C#风格,python无要求。
 9 '''
10 class IUser(object):
11     def get_user(self):
12         pass
13     
14     def insert_user(self):
15         pass
16     
17 class IDepartment(object):
18     def get_department(self):
19         pass
20     
21     def insert_department(self):
22         pass
23     
24 class CAccessUser(IUser):
25     def get_user(self):
26         print 'Access database get user information'
27         
28     def insert_user(self):
29         print 'Access database insert user information'
30         
31 class CAccessDepartment(IDepartment):
32     def get_department(self):
33         print 'Access database get department information'
34         
35     def insert_department(self):
36         print 'Access database insert department information'
37         
38 class CSqlUser(IUser):
39     def get_user(self):
40         print 'SQL database get user information'
41         
42     def insert_user(self):
43         print 'SQL database insert user information'
44         
45 class CSqlDepartment(IDepartment):
46     def get_department(self):
47         print 'SQL database get department information'
48         
49     def insert_department(self):
50         print 'SQL database insert department information'
51         
52 class IFactory(object):
53     def create_user(self):
54         pass
55     
56     def create_department(self):
57         pass
58     
59 class AccessFactory(IFactory):
60     def create_user(self):
61         temp = CAccessUser()
62         return temp
63     
64     def create_department(self):
65         temp = CAccessDepartment()
66         return temp
67     
68 class SqlFactory(IFactory):
69     def create_user(self):
70         temp = CSqlUser()
71         return temp
72     
73     def create_department(self):
74         temp = CSqlDepartment()
75         return temp
76     
77 if __name__ == '__main__':
78     factory = SqlFactory() # 如果要换成access数据库,则只需要更改这行为AccessFactory即可
79     user = factory.create_user()
80     depart = factory.create_department()
81     user.get_user()
82     depart.get_department()

2. 建造者模式

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 '''
 4 建造者模式
 5 模式特点:讲一个复杂对象的构建(Director)与它的表示(Builder)分离,使得同样的构
 6         建过程可以创建不同的表示(ConcreteBuilder)。
 7 程序实例:“画”出一个四肢健全(头身手脚)的小人。
 8 代码特点:无
 9 建造者模式是在当创建复杂对象的算法应该独立于该对象的组成部分以及他们的装配方式时适用的模式
10 '''
11 class Person(object):
12     def create_head(self):
13         pass
14     
15     def create_hand(self):
16         pass
17     
18     def create_body(self):
19         pass
20     
21     def create_foot(self):
22         pass
23     
24 class ThinPerson(Person):
25     def create_head(self):
26         print 'draw thin head'
27     
28     def create_hand(self):
29         print 'draw thin hand'
30         
31     def create_body(self):
32         print 'draw thin body'
33         
34     def create_foot(self):
35         print 'draw thin foot'
36         
37 class FatPerson(Person):
38     def create_head(self):
39         print 'draw fat head'
40     
41     def create_hand(self):
42         print 'draw fat hand'
43         
44     def create_body(self):
45         print 'draw fat body'
46         
47     def create_foot(self):
48         print 'draw fat foot'
49         
50 class Director(object):
51     def __init__(self, temp):
52         self.p = temp
53         
54     def create(self):
55         self.p.create_head()
56         self.p.create_body()
57         self.p.create_hand()
58         self.p.create_foot()
59         
60 if __name__ == '__main__':
61     p = FatPerson()
62     d = Director(p)
63     d.create()

3. 工厂模式  -- 设计的开始

定义一个用于创建对象的接口,让子类决定实例化哪一个类,工厂模式使一个类的实例化延迟到其子类

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 '''
 4 工厂模式
 5 模式特点:定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的
 6         实例化延迟到其子类。
 7 程序实例:基类雷锋类,派生出学生类和志愿者类,由这两种子类完成“学雷锋”工作。子类的创
 8         建由雷锋工厂的对应的子类完成
 9 代码特点:客户端决定实例化哪一个工厂来实现子类。
10 '''
11 class LeiFeng(object):
12     def sweep(self):
13         '''扫地'''
14         print 'LeiFeng sweep'
15 
16 class Student(LeiFeng):
17     def sweep(self):
18         print 'Student sweep'
19 
20 class Volenter(LeiFeng):
21     def sweep(self):
22         print 'Volenter sweep'
23 
24 
25 class LeiFengFactory(object):
26     def create_leifeng(self):
27         temp = LeiFeng()
28         return temp
29         
30 class StudentFactory(LeiFengFactory):
31     def create_leifeng(self):
32         temp = Student()
33         return temp
34 
35 class VolenterFactory(LeiFengFactory):
36     def create_leifeng(self):
37         temp = Volenter()
38         return temp
39     
40 if __name__ == '__main__':
41     sf = StudentFactory()
42     s = sf.create_leifeng()
43     s.sweep()
44     
45     sdf = VolenterFactory()
46     sd = sdf.create_leifeng()
47     sd.sweep()
48     
49 '''
50 如果用简单工厂模式实现,则调用一个新增加的行为,就要重新实例化一个对象
51 '''

4. 原型模式

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

 1 #!/usr/bin/env python
 2 #coding:utf-8
 3 '''
 4 原型模式
 5 模式特点:用原型实例制定创建对象的种类,并且通过拷贝这些原型创建新的对象。
 6 程序实例:从简历模板生成新的简历
 7 代码特点:简历类Resume提供的clone()方法并不是真正的clone, 只是为已存在对象增加一
 8         次引用。
 9 python为对象提供的copy模块中的copy方法和deepcopy方法已经实现了原型模式,但由于例
10 子的层次较浅,二者看不出区别。
11 '''
12 import copy
13 
14 class WorkExp(object):
15     place = ''
16     year = 0
17     
18 class Resume(object):
19     name = ''
20     age = 0
21     
22     def __init__(self, n):
23         self.name = n
24     
25     def set_age(self, a):
26         self.age = a
27     
28     def set_work_exp(self, p, y):
29         self.place = p
30         self.year = y
31         
32     def display(self):
33         print self.age
34         print self.place
35         print self.year
36         
37     def clone(self):
38         # 实际不是‘克隆’,只是返回了自己
39         return self
40     
41 if __name__ == '__main__':
42     a = Resume('a')
43     b = a.clone()
44     c = copy.copy(a)
45     d = copy.deepcopy(a)
46     
47     a.set_age(7)
48     b.set_age(12)
49     c.set_age(15)
50     d.set_age(18)
51     
52     a.set_work_exp('PrimarySchool', 1996)
53     b.set_work_exp('MidSchool', 2001)
54     c.set_work_exp('HighSchool', 2004)
55     d.set_work_exp('UniversitySchool', 2007)
56     
57     a.display()
58     b.display()
59     c.display()
60     d.display()

5. 单例模式

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

  1 #!/usr/bin/env python
  2 #coding:utf-8
  3 '''
  4 单例模式
  5 模式特点:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
  6 程序实例:公司人员的组织结构
  7 代码特点:无
  8 我要问的是,python真的需要单例模式吗?我指像其他编程语言中的单例模式。
  9 答案是:不需要!
 10 因为python有模块(module),最pythonic的单例典范。
 11 模块在一个应用程序中只有一份,它本身就是单例的,将你所需要的树形和方法,直接暴露在模
 12 块中变成模块的全局变量和方法即可!
 13 '''
 14 print '---------- 方法1 ----------'
 15 # 重构__new__方法
 16 # 并将一个类的实例绑定到类变量_instance上
 17 # 如果cls._instance为None,说明该类还没有被实例化,实例化该类,返回
 18 # 如果cls._instance不为None,直接返回cls._instance
 19 class Singleton(object):
 20     def __new__(cls, *args, **kw):
 21         if not hasattr(cls, '_instance'):
 22             org = super(Singleton, cls)
 23             cls._instance = org.__new__(cls,*args, **kw)
 24         return cls._instance
 25     
 26 class MyClass(Singleton):
 27     a = 1
 28 
 29 one = MyClass()
 30 two = MyClass()
 31 
 32 two.a = 3
 33 print one.a    #3
 34 # one 和 two 完全相同,可以用id(),==,is检查,结果全为True
 35 
 36 print '---------- 方法2 ----------'
 37 #共享属性;所谓单例就是所有引用(实例、对象)拥有相同的状态(属性)和行为(方法)
 38 #同一个类的所有实例天然拥有相同的行为(方法),
 39 #只需要保证同一个类的所有实例具有相同的状态(属性)即可
 40 #所有实例共享属性的最简单最直接的方法就是__dict__属性指向(引用)同一个字典(dict)
 41 #可参看:http://code.activestate.com/recipes/66531/
 42 class Singleton2(object):
 43     _state = {}
 44     def __new__(cls, * args, **kw):
 45         ob = super(Singleton2, cls).__new__(cls, *args, **kw)
 46         ob.__dict__ = cls._state
 47         return obj
 48 
 49 class MyClass2(Singleton2):
 50     a = 2
 51 
 52 one = MyClass2()
 53 two = MyClass2()
 54 
 55 two.a = 3
 56 print one.a # 3
 57 # one 和 two 是两个不同的对象,id, ==, is的结果都是fals
 58 # 但是one和two具有相同的__dict__属性
 59 id(one.__dict__) == id(two.__dict__)
 60 
 61 print '---------- 方法3 ----------'
 62 # 方法1的升级版本
 63 # 使用__metaclass__(元类)的高级python用法
 64 class Singleton3(object):
 65     def __init__(cls, name, bases, dict):
 66         super(Singleton3, cls).__init__(name, bases, dict)
 67         cls._instance = None
 68         
 69     def __call__(cls, *args, **kw):
 70         if cls._instance is None:
 71             cls._instance = super(Singleton3, cls).__call__(*args, **kw)
 72         return cls._instance
 73 
 74 class MyClass3(object):
 75     __metaclass__ = Singleton3
 76     
 77 one = MyClass3()
 78 two = MyClass3()
 79 # one 和 two 完全相同,可以用id(),==,is检查,结果全为True
 80 
 81 print '---------- 方法4 ----------'
 82 # 方法1更高级的版本
 83 # 使用装饰器(decorator)
 84 # 更pythonic,更elegant的方法
 85 # 单例本身根本不知道自己是单例的,因为它本身(自己的代码)并不是单例的
 86 def singleton(cls, *args, **kw):
 87     instances = {}
 88     def _singleton():
 89         if cls not in instances:
 90             instances[cls] = cls(*args, **kw)
 91         return instances[cls]
 92     return _singleton
 93 
 94 @singleton
 95 class MyClass4(object):
 96     a = 1
 97     def __init__(self, x=0):
 98         self.x = x
 99 
100 one = MyClass4()
101 two = MyClass4()
102 # one 和 two 完全相同,可以用id(),==,is检查,结果全为True
原文地址:https://www.cnblogs.com/liuq/p/5822105.html