原型模式

1.模式动机与定义

模式动机

  1. 复制一个对象,从而克隆出多个与原型对象一模一样的对象--原型模式
  2. 有些对象的创建过程较为复杂,而且需要频繁创建
  3. 通过给出一个原型对象来指明所要创建的对象的类型,然后用复制这个原型对象的办法创建出更多同类型的对象

模式定义

  1. 原型模式(Prototype Pattern):原型模式是一种对象创建型模式,用原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象
  2. 原型模式允许通过一个原型对象创建一个或多个同类型的其他对象,而无须知道任何创建的细节

2.模式结构与分析

模式结构

原型模式包含如下角色:

  1. Prototype:抽象原型类:是定义具有克隆自己的方法的接口,是所有具体原型类的公共父类,可以是抽象类,也可以是接口
  2. ConcretePrototype:具体原型类:具体原型类实现具体的克隆方法,在克隆方法中返回自己的一个克隆对象
  3. Client:客户类:客户类让一个原型克隆自身,从而创建一个新的对象。在客户类中,只需要直接实例化或通过工厂方法等方式创建一个对象,再通过调用该对象的克隆方法复制得到多个相同的对象。

模式分析

  1. 所有的Java类都继承自java.lang.Object,而Object类提供一个clone()方法,可以将一个Java对象复制一份
  2. 在Java中可以直接使用Obiect提供的clone()方法来实现对象的克隆(浅克隆)
  3. 能够实现克隆的Java类必须实现一个标识接口Cloneable,表示这个Java类支持复制
  4. 如果一个类没有实现这个接口但是调用了clone()方法,Java编译器将抛出一个CloneNotSupportedException异常
//Java内置的克隆方法,浅克隆
public class PrototypeDemo implements Cloneable{
    
    public Object clone()    //定义clone方法
    {
        Object object = null;
        try{
            object= super.clone0;  //调用object的克隆方法
        }catch (CloneNotSupportedException exception){
            System.err.println("Not support cloneable");
        }
        return object;
    }
    
}

通常情况下,一个类包含一些成员对象,在使用原型模式克隆对象时,根据其成员对象是否也克隆,原型模式可以分为两种形式:深克隆和浅克隆

  1. 浅克隆(Shallow Clone):当原型对象被复制时,只复制它本身和其中包含的值类型的成员变量,而引用类型的成员变量并没有复制,仅仅复制所考虑的对象,而不复制它所引用的成员对象。也就是其中的成员对象并不复制。
  2. 深克隆(Deep Clone):除了对象本身被复制外,对象所包含的所有成员变量也将被复制,深克隆想把要复制的对象所引用的对象都复制了一遍。

3.模式效果与应用

原型模式优点

  1. 简化对象的创建过程,通过复制一个已有实例可以提高新实例的创建效率
  2. 扩展性较好
  3. 简化创建结构,原型模式中产品的复制是通过封装在原型类中的克隆方法实现的,无须专门的工厂类来创建产品
  4. 可以使用深克隆的方式保存对象的状态,以便在需要的时候使用,可辅助实现撤销操作

原型模式缺点

  1. 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时,需要修改源代码,违背了开闭原则
  2. 在实现深克隆时需要编写较为复杂的代码,而且当对象之间存在多重的嵌套引用时,为了实现深克隆,每一层对象对应的类都必须支持深克隆,实现起来可能会比较麻烦

使用情况

  1. 创建新对象成本较大,新对象可以通过复制已有对象来获得,如果是相似对象,则可以对其成员变量稍作修改
  2. 系统要保存对象的状态,而对象的状态变化很小
  3. 需要避免使用分层次的工厂类来创建分层次的对象

模式应用

  1. 原型模式应用于很多软件中,如果每次创建一个对象要花大量时间,原型模式是最好的解决方案。很多软件提供的复制(Ctrl +C)和粘贴(Ctrl + V)操作就是原型模式的应用,复制得到的对象与原型对象是两个类型相同但内存地址不同的对象,通过原型模式可以大大提高对象的创建效率。
  2. 在Struts2中为了保证线程的安全性,Action对象的创建使用了原型模式,访问一个已经存在的Action对象时将通过克隆的方式创建出一个新的对象,从而保证其中定义的变量无须进行加锁实现同步,每一个Action中都有自己的成员变量,避免Struts1因使用单例模式而导致的并发和同步问题。
  3. 在Spring中,用户也可以采用原型模式来创建新的bean实例,从而实现每次获取的是通过克隆生成的新实例,对其进行修改时对原有实例对象不造成任何影响
posted @ 2025-12-28 21:03  QixunQiu  阅读(15)  评论(0)    收藏  举报