基本介绍
用一个已经创建的实例作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象
原型模式包含如下角色:
-
抽象原型类:规定了具体原型对象必须实现的的 clone() 方法。
-
具体原型类:实现抽象原型类的 clone() 方法,它是可被复制的对象。
-
访问类:使用具体原型类中的 clone() 方法来复制新的对象
接口类图如下:
代码实现
原型模式的克隆分为浅克隆和深克隆,具体介绍参考 Object 类介绍部分的笔记
Java中 的 Object 类中提供了 clone()
方法来实现浅克隆,实现 Cloneable 接口的类才可以被克隆
-
具体原型类:
public class Citation implements Cloneable { private String name; public void setName(String name) { this.name = name; } public String getName() { return (this.name); } public void show() { System.out.println(name + "同学:第一学期被评为三好学生。特发此状!"); } @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();// 李四 } }
模式拓展
深克隆案例:
-
原代码:
public class Citation implements Cloneable { private Student stu; // get + set public void show() { System.out.println(stu.getName() + "同学:在第一学期被评为三好学生。特发此状!"); } @Override public Citation clone() throws CloneNotSupportedException { return (Citation) super.clone(); } } //学生类 public class Student { private String name; }
-
测试代码
public static void main(String[] args) throws CloneNotSupportedException { Citation c1 = new Citation(); Student stu1 = new Student(); stu1.setName("张三"); c1.setStu(stu); Citation c2 = citation.clone(); Student stu2 = c2.getStu(); stu2.setName("李四"); citation.show(); //李四... citation1.show(); //李四... }
stu1 对象和 stu2 对象是同一个对象,将 stu2 对象中 name 属性改为李四,两个Citation对象中都是李四,这就是浅克隆的效果
-
序列化实现深克隆,或者重写克隆方法:
序列化:
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:\\b.txt")); //将c1对象写出到文件中 oos.writeObject(c1); oos.close(); //创建对象输入流对象 ObjectInputStream ois = new ObjectInputStream(new FileInputStream("C:\\b.txt")); //读取对象 Citation c2 = (Citation) ois.readObject(); //获取c2奖状所属学生对象 Student stu1 = c2.getStu(); stu1.setName("李四"); //判断stu对象和stu1对象是否是同一个对象 System.out.println("stu和stu1是同一个对象?" + (stu == stu1));//false c1.show();//张三 c2.show();//李四 } }
重写:
@Override public Citation clone() throws CloneNotSupportedException { Citation clone = (Citation) super.clone(); Student o = (Student) stu.clone(); clone.setStu(o); return clone; }