美文网首页
原型模式-java

原型模式-java

作者: JW2015 | 来源:发表于2021-12-27 16:12 被阅读0次

概念:

原型模式:用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。这种模式是实现了一个原型接口,该接口用于创建当前对象的克隆。当直接创建对象的代价比较大时,则采用这种模式。

实现方式:

抽象原型类:规定了具体原型对象必须实现的clone()方法
具体原型类:实现抽象原型类的clone()方法,它是可被复制的对象
访问类:使用具体原型类的clone()方法来复制新的对象

原型模式分为浅克隆、深克隆

实现1:(浅克隆)

java中object类中提供了clone()方法来实现浅克隆, Cloneable接口就是抽象原型类,实现了Cloneable接口的子类就是具体的原型类。如下:

public class Phone implements Cloneable {
    private String name;
    public Phone() {
        System.out.println("调用构造方法创建对象");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    protected Phone clone() throws CloneNotSupportedException {
        System.out.println("调用克隆方法创建对象");
        return (Phone) super.clone();
    }
}
public class Test {
    public static void main(String[] args) {
        try {
            Phone phone1 = new Phone();
            phone1.setName("小米手机");
            Phone phone2 = phone1.clone();
            System.out.println("phone1: "+phone1.getName()+"\nphone2: "+phone2.getName());
            phone2.setName("华为手机");
            System.out.println("phone1: "+phone1.getName()+"\nphone2: "+phone2.getName());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
    }
}
输出结果:
image.png

从输入结果可以看出,当调用原型类clone方法时,并没有再次调用构造方法。对象的属性也会一同被复制。

实现2:(深克隆)

还是以生产手机为例,这次我们在手机里添加一个CPU类引用。

public class Phone implements Cloneable, Serializable {
    private String name;
    private Cpu cpu;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Cpu getCpu() {
        return cpu;
    }

    public void setCpu(Cpu cpu) {
        this.cpu = cpu;
    }

    @Override
    protected Phone clone() throws CloneNotSupportedException {
        return (Phone) super.clone();
    }

    @Override
    public String toString() {
        return name + " : cpu name:" + cpu.getName() + " version:" + cpu.getVersion();
    }
}
public class Cpu implements Serializable {
    private String name;
    private String version;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getVersion() {
        return version;
    }

    public void setVersion(String version) {
        this.version = version;
    }
}
public class Test {
    public static void main(String[] args) {
        //一 浅克隆 引用对象指向原来的地址,修改属性值,都会一起修改
        try {
            Phone phone = new Phone();
            phone.setName("小米手机");
            Cpu cpu = new Cpu();
            cpu.setName("骁龙");
            cpu.setVersion("850");
            phone.setCpu(cpu);
            Phone phone2 = phone.clone();
            phone2.getCpu().setVersion("888");
            System.out.println(phone.toString());
            System.out.println(phone2.toString());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println("===============");
        //二 深克隆 通过序列化对象方式
        try {
            Phone phone = new Phone();
            phone.setName("华为手机");
            Cpu cpu = new Cpu();
            cpu.setName("麒麟");
            cpu.setVersion("900");
            phone.setCpu(cpu);

            ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("***/b.txt"));
            oos.writeObject(phone);
            oos.close();

            ObjectInputStream ois = new ObjectInputStream(new FileInputStream("***/b.txt"));
            Phone phone2 = (Phone) ois.readObject();
            ois.close();

            phone2.getCpu().setVersion("990");
            System.out.println(phone.toString());
            System.out.println(phone2.toString());

        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
输出结果:
image.png
由该示例可以得出:
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。(注意String虽然是引用类型,但和其他引用类型的区别在于,原先的string的值一旦创建后,就不会改变使用+/-操作,原先的字符串还是在内存中,+/-完的字符串会写入新分配的内存中,而不会改变原有的堆上的数据。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。
优点: 1、性能提高。 2、逃避构造函数的约束。
缺点: 1、配备克隆方法需要对类的功能进行通盘考虑,这对于全新的类不是很难,但对于已有的类不一定很容易,特别当一个类引用不支持串行化的间接对象,或者引用含有循环结构的时候。 2、必须实现 Cloneable 接口。

相关文章

  • 原型模式

    由于 Java 提供了对象的 clone() 方法,所以用 Java 实现原型模式很简单。 1. 模式的结构 原型...

  • Java设计模式之04_Prototype(原型模式)

    更多Java设计模式:Java设计模式-目录 原型模式是一种简单、易使用的创建型设计模式,通过给出一个原型对象来指...

  • 《JAVA与模式》之原型模式

    在阎宏博士的《JAVA与模式》一书中开头是这样描述原型(Prototype)模式的: 原型模式属于对象的创建模式。...

  • 设计模式系列-原型模式,备忘录模式

    原型模式 定义: 用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。 原型模式已经与Java融为一体...

  • 设计模式——原型模式

    在阎宏博士的《JAVA与模式》一书中开头是这样描述原型(Prototype)模式的:原型模式属于对象的创建模式。通...

  • Java架构师课程

    Java架构班开学典礼 Spring中常用的设计模式概述及工厂模式详解 单例模式及原型模式单例模式及原型模式单例模...

  • 10、原型模式(Prototype Pattern)

    1. 原型模式 1.1 简介   原型模式又叫克隆模式,顾名思义该模式是克隆对象的代码逻辑的设计。在《JAVA与模...

  • Java设计模式<原型模式>

    Java设计模式<原型模式> 意图 原型模式虽然是创建型的模式,但是与工程模式没有关系,从名字即可看出,该模式的思...

  • Java设计模式——原型模式

    Java设计模式之原型模式 回顾 Java设计模式系列的上一期写了工厂模式,那么创建类的设计模式还有生成器模式和原...

  • 总览

    1 书籍推荐 《Java设计模式》 2 分类 创建型模式 工厂方法模式 抽象工厂模式 单例模式 建造者模式 原型模...

网友评论

      本文标题:原型模式-java

      本文链接:https://www.haomeiwen.com/subject/xujyqrtx.html