设计模式-原型(Prototype)

2018-1-12 by Atlasjava


  • 设计思想

经过给出一个原型对象来指明所要建立的对象的类型,而后用复制这个原型对象的方法建立出更多同类型的对象。原始模型模式容许动态的增长或减小产品类,产品类不须要非得有任何事先肯定的等级结构,原始模型模式适用于任何的等级结构。缺点是每个类都必须配备一个克隆方法。框架

  • 应用场景

(1)种类过多没法整合成类时。
(2)不容易利用类产生对象实例时。
(3)但愿把框架和所产生的对象实例分开时。ide

  • UML 类图

Prototype UML

  • Prototype(原型) 参与者
    Prototype参与者规定复制(copy)对象实例再创建新对象实例的方法。
  • ConcretePrototype(具体原型)参与者
    ConcretePrototype参与者是实际上实现先复制对象实例再创建新对象实例的方法。
  • Client(客户)参与者
    Client参与者利用复制对象实例的方法产生另外一个新对象实例。
  • 原型模式的核心就是复制,表现到java语言就是实现Cloneable,实现clone方法,具体一点,就是clone操做时以原型为模版,分配原型一样大小的内存空间,而后建立一个跟原型同样的对象实例。
  • 简单示例
public class Prototype implements Cloneable {
    private int count;
    private ShallowCopy shallowCopy;
    private static Prototype prototype = new Prototype(0, new ShallowCopy());
    private Prototype(int count, ShallowCopy shallowCopy){
        this.count = count;
        this.shallowCopy = shallowCopy;
    }
    public Prototype clone() throws CloneNotSupportedException {
        Prototype prototype = (Prototype) super.clone();
//        prototype.shallowCopy = this.shallowCopy.clone();
        return prototype;
    }
    public static void main(String[] args) throws CloneNotSupportedException {
        Prototype p0 = Prototype.prototype;
        Prototype p1 = p0.clone();
        System.out.println(p0 == p1);
        System.out.println(p0.count == p1.count);
        System.out.println(p0.shallowCopy == p1.shallowCopy);
    }
}
class ShallowCopy implements Cloneable {
    public ShallowCopy clone() throws CloneNotSupportedException {
        return (ShallowCopy) super.clone();
    }
}
  • 成员count、shallowCopy的目的是说明clone操做的“浅拷贝”,不是原型模式的必要元素。
  • 私有化Prototype目的是模拟不经过new语法建立对象实例,测试时尽可能经过原型复制对象实例,不是原型模式的必要元素。
  • System.out.println(p0 == p1);输出false;说明clone后的对象实例是在内存中开辟的新空间。
  • System.out.println(p0.count == p1.count);输出true;其实对于基本数据类型来讲,数值是存放在对象容器中的,既然对象实例是新开辟的内存空间,数值天然也是复制一份。
  • System.out.println(p0.shallowCopy == p1.shallowCopy);输出true;说明clone的原型对象实例中引用的对象的实例并无从新开辟内存进行复制,只是复制了对引用对象实例的引用,即“浅拷贝”。
  • // prototype.shallowCopy = this.shallowCopy.clone();解开注释后,System.out.println(p0.shallowCopy == p1.shallowCopy);输出false;说明能够经过对clone对象实例中引用对象一样执行clone来进行深一些层次的拷贝,可是若是对象实例的引用对象不对引用对象的引用对象显式执行clone,没法达到传递拷贝,即彻底深拷贝。
  • 固然经过IO操做实现序列化、反序列化对象能够达到深拷贝的效果。
  • 案例鉴赏

Spring中的原型模式。测试

public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
        implements BeanDefinition, Cloneable {
    // ...
    public static final String SCOPE_DEFAULT = "";
    private String scope = SCOPE_DEFAULT;
    public void setScope(String scope) {
        this.scope = scope;
    }
    public String getScope() {
        return this.scope;
    }
    /**
     * Return whether this a <b>Singleton</b>, with a single shared instance
     * returned from all calls.
     * @see #SCOPE_SINGLETON
     */
    public boolean isSingleton() {
        return SCOPE_SINGLETON.equals(scope) || SCOPE_DEFAULT.equals(scope);
    }
    /**
     * Return whether this a <b>Prototype</b>, with an independent instance
     * returned for each call.
     * @see #SCOPE_PROTOTYPE
     */
    public boolean isPrototype() {
        return SCOPE_PROTOTYPE.equals(scope);
    }
    /**
     * Public declaration of Object's {@code clone()} method.
     * Delegates to {@link #cloneBeanDefinition()}.
     * @see Object#clone()
     */
    public Object clone() {
        return cloneBeanDefinition();
    }
    /**
     * Clone this bean definition.
     * To be implemented by concrete subclasses.
     * @return the cloned bean definition object
     */
    public abstract AbstractBeanDefinition cloneBeanDefinition();
    // ...
}
相关文章
相关标签/搜索