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


    --------------------------------- 创建型模式 --------------------------------
    - 隐藏了这些类的实例是如何被创建和放在一起,整个系统关于这些对象所直到的  -
    - 由抽象类所定义的接口。这样,创建型模式在创建了什么、谁创建它、它是怎么  -
    - 被创建的,以及何时创建这些方面提供了很大的灵活性。                               -
    -----------------------------------------------------------------------------
    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
  • 相关阅读:
    mysql,windows自动备份设置
    彻底搞清楚javascript中的require、import和export
    Spring Boot 打包报错Failed to execute goal org.apache.maven.plugins:mavenresourcesplugin:3.2.0
    Spring AOP 切点切面
    12.5M 30M 90M DEM免费下载!【转】
    JS 中的数组遍历方式效率比较[转]
    cesium加载CAD模型(.dwg)
    Cesium发布下一代3D Tiles规范预览
    cesium点击面高亮事件[转]
    MySQL 5.7及8.0版本数据库的root密码遗忘的解决办法
  • 原文地址:https://www.cnblogs.com/liuq/p/5822105.html
Copyright © 2020-2023  润新知