设计模式:原型模式

原型模式类似克隆技术,通过以某个对象为原型,复制出新对象。克隆出的对象属性和原型对象相同。但克隆出的新对象不会改变原来对象。

   优势:对象某些创建对象代价高可以使用该模式,效率高。

实现:java语言直接支持原型模式,因为所有java对象继承自Object, 里面由一个clone()方法,可以将一个对象复制一份。但要使该对象支持复制

需要实现一个接口Cloneable。如果直接调用clone方法不实现接口编译器会抛出CloneNotSupoortedException异常。

简单说明下java对象的复制:

  1.java语言提供 的Cloneable接口,只是起到在运行时期告诉jvm可以在该类上使用clone()方法。通过该方法得到一个对象的复制。

  2.Object类本身不实现Cloneable接口。所以需要复制的类没有实现该接口会抛异常。

/**
*测试克隆
**/
public class TestClone implements Cloneable { private Integer age; private String name; public TestClone(Integer age, String name) { this.age = age; this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override protected Object clone() throws CloneNotSupportExcetion{ return (TestClone)super.clone(); } @Override public String toString() { return "TestClone{" + "age=" + age + ", name='" + name + '\'' + '}'; } public static void main(String[] args) { TestClone temp1 = new TestClone(1, "tom"); TestClone temp2 = (TestClone) temp1.clone(); System.out.println("temp1: "+ temp1);//temp1: TestClone{age=1, name='tom'} System.out.println("temp2: "+ temp2);//temp2: TestClone{age=1, name='tom'} System.out.println(temp1 == temp2); //false } }

  结果上,克隆对象和原对象性质一样。但不是同一个对象。这里体现的是浅克隆。深克隆和它区别是,克隆后的对象引用是另一个对象。

这个例子深克隆和浅克隆表现一直,是因为属性是基本类型,以及string类型。

关于深克隆和浅克隆这里就不扩展了。

回到模式上:原型模式主要两种,这两种本质上其实是一致。只是表现新式不一样。

  1. 简单形式:和例子中一样的方式。

  2. 登记形式:将简单新式跟进一步抽象化。增加对需要创建的原型对象管理类。

/**
 * 抽象原型角色
 */
public interface Prototype extends Cloneable{
    public Object clone();
}

  

/**
 * 具体原型角色实现抽象原型角色的接口,也就是clone()方法
 */
public class ConcretePrototype implements Prototype {
    @Override
    public Object clone() {
        try {
            return (Prototype)super.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        return null;
    }
}

  

/**
 * 原型管理器,管理所有原型对象,并提供对外界添加原型对象和获取原型对象
 */
public class PrototypeManager {

    private List<Prototype> objects = new ArrayList<>();

    /**
     * 增加一个对象
     * @param obj
     */
    public void add(Prototype obj){
        objects.add(obj);
    }

    /**
     * 获取一个对象
     */
    public Prototype get(int id){
        return objects.get(id);
    }
}

  

public class Client {
    public static void main(String[] args) {

        PrototypeManager mgr = new PrototypeManager();
        Prototype prototype = new ConcretePrototype();
        Prototype copyPrototype = (Prototype) prototype.clone();
        mgr.add(copyPrototype);
        copyPrototype = mgr.get(0);

    }

}

  两种形式各有长短处。如果需要创建的原型对象数目少就可以直接简单新式。如果要创建的原型对象数目多不固定,

则建议以登记形式管理原型对象。

  

  

 

posted @ 2018-12-23 12:30  小阿Q的博客  阅读(132)  评论(0编辑  收藏  举报