4.设计模式之二:原型模式【建立型模式】

在有些系统中,存在大量相同或类似对象的建立问题,若是用传统的构造函数来建立对象,会比较复杂且耗时耗资源,用原型模式生成对象就很高效,就像孙悟空拔下猴毛轻轻一吹就变出不少孙悟空同样简单。python

定义与特色

原型(Prototype)模式的定义以下:用一个已经建立的实例做为原型,经过复制该原型对象来建立一个和原型相同或类似的新对象。函数

在这里,原型实例指定了要建立的对象的种类。用这种方式建立对象很是高效,根本无须知道对象建立的细节。spa

例如,Windows 操做系统的安装一般较耗时,若是复制就快了不少。在生活中复制的例子很是多,这里不一一列举了。操作系统

结构与实现

模式的结构

原型模式包含如下主要角色。3d

  1. 抽象原型类:规定了具体原型对象必须实现的接口。
  2. 具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
  3. 访问类:使用具体原型类中的 clone() 方法来复制新的对象。

模式的实现

from copy import copy, deepcopy
class Prototype(object):
    '''抽象原型类'''
    def clone(self):
        # 浅拷贝
        pass

    def deep_clone(self):
        # 深拷贝
        pass

class Realizetype(Prototype):
    '''具体原型类'''
    cls_s = [[1, 2, 3], 4, 5, 6]
    def __init__(self):
        self.s = [[1, 2, 3], 4, 5, 6]
        print("具体原型类实例化成功!")

    def clone(self):
        print("具体原型类潜复制成功!")
        return copy(self)

    def deep_clone(self):
        print("具体原型类深复制成功!")
        return deepcopy(self)

if __name__ == '__main__':
    rt = Realizetype()
    copy_rt = rt.clone()
    deep_copy_rt = rt.deep_clone()
    
    rt.s[0][1] = 10
    rt.cls_s[0][1] = 10
    print(rt.s, copy_rt.s, deep_copy_rt.s)
    print(rt.cls_s, copy_rt.cls_s, deep_copy_rt.cls_s)
具体原型类实例化成功!
具体原型类潜复制成功!
具体原型类深复制成功!
[[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 2, 3], 4, 5, 6]
[[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6] [[1, 10, 3], 4, 5, 6]

从结果中能够发现,潜复制中可变元素中嵌套有可变元素,一旦嵌套中的可变元素发生变化,潜复制的值也会发生变化,即原来的[1,2, 3]变成了[1, 10, 3]。code

可是类属性却会跟着变化,由于类属性只属于类,不属于实例。注意这种差别只有在可变元素中发生。对象

【例1】用原型模式生成“三好学生”奖状blog

分析:同一学校的“三好学生”奖状除了获奖人姓名不一样,其余都相同,属于类似对象的复制,一样能够用原型模式建立,而后再作简单修改就能够了。图 4 所示是三好学生奖状生成器的结构图。接口

from copy import copy
class Prototype(object):
    def clone(self):
        pass

class Citation(Prototype):
    def __init__(self, name, info, college):
        self.__name = name
        self.__info = info
        self.__college = college
        print("奖状建立成功!")

    def clone(self):
        return copy(self)

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        self.__name = name

    @property
    def info(self):
        return self.__info

    @info.setter
    def info(self, info):
        self.__info = info

    @property
    def college(self):
        return self.__college

    @college.setter
    def college(self, college):
        self.__college = college

    def show(self):
        print(self.__name, self.__info, self.__college)

if __name__ == '__main__':
    st1 = Citation("zhang", "三好学生", "南京大学")
    st2 = st1.clone()
    st2.name = "wang"
    st2.college = "北京大学"
    st1.show()
    st2.show()
奖状建立成功!
zhang 三好学生 南京大学
wang 三好学生 北京大学

应用场景

原型模式一般适用于如下场景。资源

  • 对象之间相同或类似,即只是个别的几个属性不一样的时候。
  • 对象的建立过程比较麻烦,但复制比较简单的时候。

原型模式的扩展

原型模式可扩展为带原型管理器的原型模式,它在原型模式的基础上增长了一个原型管理器 PrototypeManager 类。该类用 HashMap 保存多个复制的原型,Client 类能够经过管理器的 get(String id) 方法从中获取复制的原型。其结构图如图所示。

【例2】用带原型管理器的原型模式来生成包含“圆”和“正方形”等图形的原型,并计算其面积。

分析:本实例中因为存在不一样的图形类,例如,“圆”和“正方形”,它们计算面积的方法不同,因此须要用一个原型管理器来管理它们,图所示是其结构图。

相关文章
相关标签/搜索