zoukankan      html  css  js  c++  java
  • 设计模式之 原型模式

      在日常软件系统开发中,某些对象的创建new即为复杂,而且我们需要使用多个相同的实例。这样如果我们依旧使用new去进行创建。就会增加系统的复杂度和增加代码之间的耦合度。但是我们使用前面介绍的工厂模式的话,随着产品类型的增多,子类也会随之增多。维护代码的难度也就会越来越大,所以这里暂时不适合使用工厂模式。由于实例都是一样的,类型相同,但只是实例的参数和状态可能不同,这时若已经有一个对象,我们便可以结合下面讲述的原型模式,即通过一个原型对象,克隆拷贝出许多其他相同的对象来。

    原型模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

    例如,一个对象需要在一个高代价的数据库操作之后被创建。我们可以缓存该对象,在下一个请求时返回它的克隆,在需要的时候更新数据库,以此来减少数据库调用。

    一、来由

      在面对软件系统设计的过程中,会面临着”复杂对象”的创建,然而对象可能会由于需求的变动而进行变动。那么我们又需要保持接口的稳定性。这时如何保证应对这种变化呢?

      创建型模式一般是用来创建一个新的对象,然后我们使用这个对象完成一些对象的操作,我们通过原型模式可以快速的创建一个对象而不需要提供专门的new()操作就可以快速完成对象的创建,这无疑是一种非常有效的方式,快速的创建一个新的对象。

    二、定义

      原型模式是创建型模式中的一种较为特殊的模式,用于 克隆现有的对象  。

    Specify the kind of objects to create using a prototypical instance, and create new objects by copying this prototype. (使用原型实例指定将要创建的对象类型,通过复制这个实例创建新的对象。)

    在使用原型模式克隆对象时,根据其成员对象是否也克隆,原型模式可以分为两种形式:深克隆 和 浅克隆 。

    浅拷贝:只复制指针值而不是实际资源。即只拷贝对象中的基本数据类型(8种),对于数组、容器、引用对象等都不会拷贝。

    深拷贝:不仅复制指针值,还复制指针所指向的资源。即不仅能拷贝基本数据类型,还能拷贝那些数组、容器、引用对象等。

    三、角色分析(可认为是“三个角色”,也可认为是“两个角色”,抽象原型类 和 具体原型类 可合并成一个原型类):

      1 、Prototype(抽象原型类)
    Prototype 角色负责定义用于复制现有实例来生成新实例的方法,使其拥有被克隆复制的功能。同时,此角色定义了具体原型类所需的实现的方法。

      2 、Concrete Prototype(具体原型类)
    Concrete Prototype 角色负责实现复制现有实例并生成新实例的方法。实现抽象原型角色的克隆接口,或者继承抽象原型类。

      3 、Client(客户类/使用者)
    Client 角色负责使用复制实例的方法生成新的实例,即用户使用复制粘贴的功能。

    四、类图

    五、优点: 

      1、性能提高。当创建新的对象实例较为复杂时,使用原型模式可以简化对象的创建过程,通过一个已有实例可以提高新实例的创建效率,也可以动态增加或减少产品类,也可以使用深克隆的方式保存对象的状态。

      2、逃避构造函数的约束。

    六、缺点: 

      1、必须实现 Cloneable 接口,即需要为每一个类配备一个克隆方法,在实现深克隆时需要编写较为复杂的代码。

      2、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对已有的类进行改造时,不一定是件容易的事,必须修改其源代码,违背了“开闭原则”。

    七、实际应用案例  

      1、原型模式应用于很多软件中,如果每次创建一个对象要花大量时间,原型模式是最好的解决方案。很多软件提供的复制(Ctrl + C)和粘贴(Ctrl + V)操作就是原型模式的应用,复制得到的对象与原型对象是两个类型相同但内存地址不同的对象,通过原型模式可以大大提高对象的创建效率。

      2、在Struts2中为了保证线程的安全性,Action对象的创建使用了原型模式,访问一个已经存在的`Action对象时将通过克隆的方式创建出一个新的对象,从而保证其中定义的变量无须进行加锁实现同步,每一个Action中都有自己的成员变量,避免Struts1因使用单例模式而导致的并发和同步问题。

      3、在Spring中,用户也可以采用原型模式来创建新的bean实例,从而实现每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响。

    参考:

      设计模式之原型模式(Java代码实现)

      深入理解原型模式 ——通过复制生成实例

    共同学习,共同进步,若有补充,欢迎指出,谢谢!

  • 相关阅读:
    对linux内核创建flash上的各分区源码进行分析
    如何调试ubifs文件系统
    如何打开linux内核中dev_dbg的开关
    配置linux内核输出所有的log信息
    uboot向linux传递输出任何log信息的方法
    redis:Invalid input of type: 'bool' type. Convert to a byte,string or number first
    dd命令参数解析
    shell脚本中使用什么工具进行计算
    openwrt的编译方法
    bootstraptable表格columns 隐藏方法
  • 原文地址:https://www.cnblogs.com/dengguangxue/p/11630847.html
Copyright © 2011-2022 走看看