设计模式之 原型模式

  在日常软件系统开发中,某些对象的创建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代码实现)

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

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

原文地址:https://www.cnblogs.com/dengguangxue/p/11630847.html