设计模式之原型模式 Prototype

public class Sheep implements Cloneable,Serializable{

    private String sname;
    private Date birthday;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        return obj;
    }

    public Sheep(String sname, Date birthday) {
        super();
        this.sname = sname;
        this.birthday = birthday;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

}

sheep类

public class Sheep2 implements Cloneable{

    private String sname;
    private Date birthday;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();

        //添加如下代码实现深克隆
        Sheep2 s = (Sheep2) obj;
        s.birthday = (Date) this.birthday.clone();  //把属性也进行克隆

        return obj;
    }

    public Sheep2(String sname, Date birthday) {
        super();
        this.sname = sname;
        this.birthday = birthday;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

}

sheep2类

/**
 * 测试原型模式--浅克隆
 * @author bzhx
 * 2017年3月10日
 */
public class Client {

    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date(125545225555L);
        Sheep s1  = new Sheep("少利",date);

        System.out.println("测试浅复制");
        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());

        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());

        Sheep s2 = (Sheep) s1.clone();
        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());
    }

}

测试浅克隆

/**
 * 原型模式(深克隆)
 * @author bzhx
 * 2017年3月10日
 */
public class Client2 {

    public static void main(String[] args) throws CloneNotSupportedException {
        Date date = new Date(125545225555L);

        Sheep2 s1  = new Sheep2("少利",date);
        Sheep2 s2 = (Sheep2) s1.clone(); //实现深复制

        System.out.println("测试深复制");
        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());

        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());

        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());
    }
}

测试深克隆

public class Client3 {

    public static void main(String[] args) throws CloneNotSupportedException, ClassNotFoundException, IOException {

        Date date = new Date(125545225555L);
        Sheep s1  = new Sheep("少利",date);

        System.out.println(s1);
        System.out.println(s1.getSname());
        System.out.println(s1.getBirthday());

        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(bos);

        oos.writeObject(s1);
        byte[] bytes = bos.toByteArray();

        ByteArrayInputStream bis = new ByteArrayInputStream(bytes);
        ObjectInputStream  ois = new ObjectInputStream(bis);

        Sheep s2 = (Sheep) ois.readObject(); //克隆好的对象

        System.out.println("修改原型对象的属性值");
        date.setTime(5586558657741L);
        System.out.println(s1.getBirthday());

        s2.setSname("少少利");   //clone后的新对象还可以修改
        System.out.println(s2);  //clone对象不一样
        System.out.println(s2.getSname()); //但是clone后的内容一致
        System.out.println(s2.getBirthday());

    }

}

深复制,使用序列化和反序列化的方式实现深复制

/**
 * 测试普通new方式创建对象和clone方式创建对象的效率差异
 * 如果需要短时间创建大量对象,并且new的过程比较耗时,则可以考虑使用原型模式
 * @author bzhx
 * 2017年3月10日
 */

public class Client4 {

    //new创建对象
    public static void testNew(int size){
        long start = System.currentTimeMillis();
        for (int i = 0; i < size; i++) {
            Laptop t = new Laptop();
        }
        long end = System.currentTimeMillis();
        System.out.println("new的方式创建耗时:" + (end-start));
    }

    //clone创建
    public static void testClone(int size) throws CloneNotSupportedException{
        long start = System.currentTimeMillis();
        Laptop t = new Laptop();
        for (int i = 0; i < size; i++) {
            Laptop temp = (Laptop) t.clone();
        }
        long end = System.currentTimeMillis();
        System.out.println("Clone的方式创建耗时:" + (end-start));
    }

    public static void main(String[] args) throws Exception {
        testNew(1000);
        testClone(1000);
    }

}

class Laptop implements Cloneable{

    public Laptop(){
        try {
            Thread.sleep(10);  //模拟创建对象耗时的过程
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        Object obj = super.clone();
        return obj;
    }
}

测试普通new方式创建对象和clone方式创建对象的效率差异

深复制(深克隆)与浅复制(浅克隆)

⑴浅复制(浅克隆)

被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象。换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象。

⑵深复制(深克隆)

被复制对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

时间: 2024-11-05 19:31:25

设计模式之原型模式 Prototype的相关文章

二十四种设计模式:原型模式(Prototype Pattern)

原型模式(Prototype Pattern) 介绍用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象. 示例有一个Message实体类,现在要克隆它. MessageModel using System; using System.Collections.Generic; using System.Text; namespace Pattern.Prototype { /// <summary> /// Message实体类 /// </summary> publi

设计模式 笔记 原型模式 prototype

//---------------------------15/04/07---------------------------- //prototype 原型模式--对象创建型模式 /* 1:意图:用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 2:动机: 3:适用性: 1>当一个系统应该独立于它的产品创建.构成和表示时 2>当要实例化的类是在运行时刻制定时,例如通过动态装载 3>为了避免创建一个与产品类层次平行的工厂类层次时 4>当一个类的实例只能有几个不同状

【设计模式】—— 原型模式Prototype

前言:[模式总览]——————————by xingoo 模式意图 由于有些时候,需要在运行时指定对象时哪个类的实例,此时用工厂模式就有些力不从心了.通过原型模式就可以通过拷贝函数clone一个原有的对象,给现在的对象使用,从而创建更多的同类型的对象. 模式结构 [简单原型模式]用于原型的版本不多的时候 [登记模式的原型模式]如果原型的实现很多种版本,那么通过一个登记管理类,可以方便的实现原型的管理. Prototype 原型接口,定义原型的结构. ConcretePrototype 原型的具体

创建型设计模式之原型模式(Prototype)

结构   意图 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性 当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或者 当一个类的实例只能有几个不同状态组合中的一种时.建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些. 1 using System; 2 3 // Objects which are to work as prototypes must be based on class

Java设计模式四: 原型模式(Prototype Pattern)

网上找了好多这个模型的资料说的都不透彻,看了半天都是云里雾里.只好自己操刀研究一把. 原型模式是一种创建型设计模式,它通过复制一个已经存在的实例来返回新的实例,而不是新建实例.被复制的实例就是我们所称的原型,这个原型是可定制的.原型模式多用于创建复杂的或者耗时的实例, 因为这种情况下,复制一个已经存在的实例可以使程序运行更高效,或者创建值相等,只是命名不一样的同类数据. 原型模式中的拷贝分为"浅拷贝"和"深拷贝":浅拷贝: 对值类型的成员变量进行值的复制,对引用类型

设计模式之原型模式prototype

1.原型模式的使用和本质.以及优势: a.通过 new 产生一个对象需要非常繁琐的数据准备或者访问权限,则可以使用原型模式. b.原型模式的使用就是 java 中的克隆技术,以某个对象为原型,复制出新的对象.显然,新的对象具备原型对象的特点. c.其优势有:效率高(直接克隆,避免了重新执行构造过程步骤). d.克隆类似于 new, 但是不同于 new .new 创建新的对象属性采用的是默认值.克隆出的对象的属性值完全和原型对象相同.并且克隆出来的新对象改变不会影响原型对象.(可以对克隆对象修改属

谈谈设计模式~原型模式(Prototype)

返回目录 原型模式是创建型模式的一种,其特点在于通过“复制”一个已经存在的实例来返回新的实例(clone),而不是新建(new)实例.被复制的实例就是我们所称的“原型”,这个原型是可定制的. 原型模式多用于创建复杂的或者耗时的实例,因为这种情况下,复制一个已经存在的实例使程序运行更高效:或者创建值相等,只是命名不一样的同类数据. 从原型模式的概念中,我们可以看到,在这个模式里,拷贝是个很重要的概念,即在不创建对象的情况下,返回一个已有对象,这就是拷贝去实现的,在面向对象的编程世界里,拷贝分为浅拷

C#设计模式(6)——原型模式(Prototype Pattern)

一.引言 在软件系统中,当创建一个类的实例的过程很昂贵或很复杂,并且我们需要创建多个这样类的实例时,如果我们用new操作符去创建这样的类实例,这未免会增加创建类的复杂度和耗费更多的内存空间,因为这样在内存中分配了多个一样的类实例对象,然后如果采用工厂模式来创建这样的系统的话,随着产品类的不断增加,导致子类的数量不断增多,反而增加了系统复杂程度,所以在这里使用工厂模式来封装类创建过程并不合适,然而原型模式可以很好地解决这个问题,因为每个类实例都是相同的,当我们需要多个相同的类实例时,没必要每次都使

【设计模式】——原型模式

原型模式(Prototype),用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 下图是原型模式的结构图: 原型模型其实就是一个对象再创建另外一个可定制的对象,而且不需任何创建的细节,我们来看看基本的原型模式代码. //原型类 class Prototype { private: string id; public: Prototype(string id) { this->id=id; } string GetId() { return id; } virtual Protot