原型模式也属于创建型模式,该模式的思想就是将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象。其中包含了深复制和浅复制两种复制。
浅复制:将一个对象复制后,基本数据类型的变量都会重新创建,而引用类型,指向的还是原对象所指向的。
深复制:将一个对象复制后,不论是基本数据类型还有引用类型,都是重新创建的。
深复制的实现方式有2种,
①单独对其中对象再次克隆
②实现序列化,通过流的方式实现
简单来说,就是深复制进行了完全彻底的复制,而浅复制不彻底。
模式类型 | 优点 | 缺点 | 应用场景 |
原型模式 |
1、性能提高。 2、逃避构造函数的约束。 |
1.必须实现 Cloneable 接口 2.深复制需要进序列化 |
1.一个对象多个修改者的场景 2.性能和安全要求的场景 3.资源优化场景 |
创建Prototype类
package com.designpatterns.create.prototype; import java.io.*; public class Prototype implements Cloneable, Serializable { private static final long serialVersionUID = 6700381124074207478L; private String string; private SerializableObject obj; /* 浅复制 */ public Object clone() throws CloneNotSupportedException { Prototype proto = (Prototype) super.clone(); return proto; } /* 深复制 */ public Object deepClone() throws IOException, ClassNotFoundException { /* 写入当前对象的二进制流 */ ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(bos); oos.writeObject(this); /* 读出二进制流产生的新对象 */ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); return ois.readObject(); } public String getString() { return string; } public void setString(String string) { this.string = string; } public SerializableObject getObj() { return obj; } public void setObj(SerializableObject obj) { this.obj = obj; } @Override public String toString() { final StringBuffer sb = new StringBuffer("Prototype{"); sb.append("string='").append(string).append('\''); sb.append(", obj=").append(obj); sb.append('}'); return sb.toString(); } }
创建SerializableObject类
package com.designpatterns.create.prototype; import java.io.Serializable; public class SerializableObject implements Serializable { private static final long serialVersionUID = 5415290762824927634L; private Integer age; private String name; private String address; public SerializableObject(Integer age, String name, String address) { this.age = age; this.name = name; this.address = address; } 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; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { final StringBuffer sb = new StringBuffer("SerializableObject{"); sb.append("age=").append(age); sb.append(", name='").append(name).append('\''); sb.append(", address='").append(address).append('\''); sb.append('}'); return sb.toString(); } }
测试
/** * *原型模式:将一个对象作为原型,对其进行复制、克隆,产生一个和原对象类似的新对象 * 浅复制: 只赋值基础类型,引用类型和原对象的致 * 深复制: 完全赋值,引用类型也是全新的对象 * @author wyj * @date 2020/8/7 14:25 */ public class PrototypeTest { public static void main(String[] args) throws Exception { Prototype prototype = new Prototype(); prototype.setString("么么哒"); SerializableObject serializableObject = new SerializableObject(100, "赵波蓝", "四川"); prototype.setObj(serializableObject); /*浅复制*/ Prototype o1 = (Prototype)prototype.clone(); System.out.println(serializableObject.equals(o1.getObj())); /*深复制*/ Prototype o = (Prototype)prototype.deepClone(); System.out.println(serializableObject.equals(o.getObj())); } }
个人学习随笔,若是帮助到您,请给个推荐,或者评论一下下,谢谢了哟。若有不懂之处,请联系QQ:351094262(验证信息:博客园),原创不易,转载请标明出处!