设计模式——原型模式
创始人
2025-05-29 06:23:14

原型模式

用一个已经创建的对象作为原型,通过复制该原型对象来创建一个和原型对象相同的新对象。

原型模式包含如下角色:

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

类图请添加图片描述

原型模式的克隆分为浅克隆和深克隆。
浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

浅克隆案例

用浅克隆生成学生奖状

类图

在这里插入图片描述

奖状类代码

/*** @author Watching* * @date 2023/3/16* * Describe:*/
public class Citations implements Cloneable {public Citations() {System.out.println("执行构造方法");}private Student student = new Student();public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}@Overrideprotected Citations clone() throws CloneNotSupportedException {System.out.println("执行克隆方法");return (Citations) super.clone();}
}

Student为一个引用类型的成员变量

测试类代码

/*** @author Watching* * @date 2023/3/16* * Describe:* 浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象* 浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。*/
public class Client {public static void main(String[] args) throws CloneNotSupportedException {Citations citations = new Citations();Citations clone = citations.clone();//浅克隆是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象System.out.println(citations == clone);//结果为falseSystem.out.println(citations.getStudent() == clone.getStudent());//结果为truecitations.getStudent().setName("张三");clone.getStudent().setName("李四");System.out.println(citations.getStudent().getName());//结果是李四,说明clone对象修改Student类型的变量导致citations中的变量修改了。//说明两个对象的Student引用都是指向的同一个地址}
}

根据结果可以得出结论,实现Cloneable接口使用clone()方法生成的对象是浅拷贝。

深克隆案例

这里我们使用对象流序列化来实现深克隆,我们在破坏单例模式中也使用过对象流序列化
奖状类代码
奖状类代码基本不变,唯一不同的就是不需要实现Cloneable接口了,因为我们这个案例不需要使用clone()方法来克隆对象。并且需要实现一个Serializable接口,因为需要序列化。而且Cations奖状类中的引用成员变量也需要实现Serializable接口,它也需要序列化

/*** @author Watching* * @date 2023/3/16* * Describe:*/
public class Citations implements  Serializable {public Citations() {System.out.println("执行构造方法");}private Student student = new Student();public Student getStudent() {return student;}public void setStudent(Student student) {this.student = student;}
}

测试类代码
测试类代码需要做一些改变,使用序列化代替clone。

/*** @author Watching* * @date 2023/3/16* * Describe:* 深克隆:创建一个新对象,属性中引|用的其他对象也会被克隆,不再指向原有对象地址。*/
public class Client {public static void main(String[] args) throws CloneNotSupportedException, IOException, ClassNotFoundException {Citations citations = new Citations();//使用序列化深拷贝一个Citations对象出来,想要使用序列化,必须保证该类及其引用类型成员实现Serializable接口ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(new File("D:\\d.txt")));oos.writeObject(citations);ObjectInputStream ois = new ObjectInputStream(new FileInputStream(new File("D:\\d.txt")));Citations citations1 = (Citations) ois.readObject();citations.getStudent().setName("张三");citations1.getStudent().setName("李四");System.out.println(citations.getStudent().getName());//结果是张三//说明修改citations1中的Student类型成员变量并没有影响到citation中的成员变量}
}

根据结果可以得出结论,序列化是可以得到一个“完全崭新的对象的”(深拷贝)

重点

浅克隆:创建一个新对象,新对象的属性和原来对象完全相同,对于非基本类型属性,仍指向原有属性所指向的对象的内存地址。
深克隆:创建一个新对象,属性中引用的其他对象也会被克隆,不再指向原有对象地址。

相关内容

热门资讯

实测分享.肆喜麻将有没有挂.原... 亲.肆喜麻将这款游戏是可以开挂的,确实是有挂的,通过添加客服【8435338】很多玩家在这款游戏中怀...
科普实测“拱趴大菠萝透视挂辅助... 您好:拱趴大菠萝这款游戏可以开挂,确实是有挂的,需要软件加微信【4194432】,很多玩家在拱趴大菠...
今日重大通报“情怀宜春麻将到底... 亲:情怀宜春麻将这款游戏是可以开挂的,确实是有挂的,添加客服【3671900】很多玩家在这款游戏中怀...
独家讲解.新老夫子炸金花有没有... 独家讲解.新老夫子炸金花有没有挂.(必胜开挂神器)您好:新老夫子炸金花这款游戏可以开挂,确实是有挂的...
今日分享.八闽福建麻将有没有挂... 今日分享.八闽福建麻将有没有挂.外卦神器下载!亲,八闽福建麻将这个游戏其实有挂的,确实是有挂的,需要...