本文共 4198 字,大约阅读时间需要 13 分钟。
原型模式(Prototype Pattern)是一种创建型设计模式,通过使用一个已经创建的实例作为原型,来创建一个与原型对象相同的新对象。这种模式在软件开发中非常有用,特别是在对象的创建过程复杂或资源消耗高时。
原型模式的核心思想是:用一个原型对象作为模板,通过复制该原型对象来创建新的对象。这种方式可以减少新对象创建时的资源消耗,同时保持新对象与原型对象之间的一致性。
原型模式的主要角色包括:
clone() 方法。clone() 方法,且是可以被复制的对象。clone() 方法来创建新对象。类图如下:
接口类图如下:
在 Java 中,Object 类中的 clone() 方法默认实现了浅克隆(Shallow Copy)。Cloneable 接口是抽象原型类,具体原型类需要实现这个接口。
要实现深克隆,需使用序列化(Serializable)接口,并通过对象流(ObjectInputStream 和 ObjectOutputStream)进行操作。
// 实现Cloneable接口的具体原型类public class Realizetype implements Cloneable { public Realizetype() { System.out.println("具体的原型对象创建完成!"); } @Override protected Realizetype clone() throws CloneNotSupportedException { System.out.println("具体原型复制成功!"); return (Realizetype) super.clone(); }}// 测试访问类public class PrototypeTest { public static void main(String[] args) throws CloneNotSupportedException { Realizetype r1 = new Realizetype(); Realizetype r2 = r1.clone(); System.out.println("r1和r2是否是同一个对象?" + (r1 == r2)); // 输出: false }} 假设我们需要生成多个具有相同属性的“三好学生”奖状,只需复制一个奖状并修改其中的姓名即可。
public class Citation implements Cloneable { private String name; public void setName(String name) { this.name = name; } public String getName() { return name; } public void show() { System.out.println(name + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!"); } @Override public Citation clone() throws CloneNotSupportedException { return (Citation) super.clone(); }} public class CitationTest { public static void main(String[] args) throws CloneNotSupportedException { Citation c1 = new Citation(); c1.setName("张三"); Citation c2 = c1.clone(); c2.setName("李四"); c1.show(); c2.show(); }} 输出结果:
张三同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!李四同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
要实现深克隆,需使用序列化接口,并通过对象流进行操作。
// 实现序列化接口的具体原型类public class Citation implements Serializable { private Student stu; public Student getStu() { return stu; } public void setStu(Student stu) { this.stu = stu; } void show() { System.out.println(stu.getName() + "同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!"); } @Override public Citation clone() throws CloneNotSupportedException { return (Citation) super.clone(); }}// 实现序列化接口的学生类public class Student implements Serializable { private String name; private String address; public Student(String name, String address) { this.name = name; this.address = address; } public Student() { } 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; }} public class CitationTest1 { public static void main(String[] args) throws Exception { Citation c1 = new Citation(); Student stu = new Student("张三", "西安"); c1.setStu(stu); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("C:\\Users\\Think\\Desktop\\b.txt")); oos.writeObject(c1); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\Users\\Think\\Desktop\\b.txt")); Citation c2 = (Citation) ois.readObject(); ois.close(); Student stu1 = c2.getStu(); stu1.setName("李四"); System.out.println("stu和stu1是否是同一个对象?" + (stu == stu1)); // 输出: false c1.show(); c2.show(); }} 运行结果:
stu和stu1不是同一个对象。张三同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!李四同学:在2020学年第一学期中表现优秀,被评为三好学生。特发此状!
说明:stu 和 stu1 是同一个对象的引用,但 stu1 的 name 属性已修改为“李四”。
转载地址:http://szhfk.baihongyu.com/