• 设计模式-原型模式


    模式意图

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

    对象的创建如果比较复杂,就可以使用原型模式创建对象。

    实现类的性能或安全要求比较高,可以让该类实现克隆接口,通过克隆获取对象而不是new。 

    分类

    浅克隆:克隆的新对象与原对象完全相同,对于非基本类型的属性,仍指向原对象的内存地址。

    深克隆:克隆的新对象与原对象内存地址不同。

     结构

    • 抽象原型类
    • 具体原型类:实现抽象原型类的clone方法
    • 访问类

    浅克隆实现

    实现了Cloneable接口的类并且重写clone方法就可以被克隆

     

    1. class Realizetype implements Cloneable{
    2. private String name = "zz";
    3. private int age = 18;
    4. Realizetype(){
    5. System.out.println("原型对象创建完成");//只打印了一次,说明原型模式底层不是通过构造器实现
    6. }
    7. public String getName() {
    8. return name;
    9. }
    10. public void setName(String name) {
    11. this.name = name;
    12. }
    13. public int getAge() {
    14. return age;
    15. }
    16. public void setAge(int age) {
    17. this.age = age;
    18. }
    19. @Override
    20. public Realizetype clone() throws CloneNotSupportedException {
    21. return (Realizetype) super.clone();//返回原型类,原型的属性和方法都不变
    22. }
    23. }
    24. public class Client{
    25. public static void main(String[] args) throws CloneNotSupportedException {
    26. Realizetype r = new Realizetype();
    27. Realizetype cl;
    28. cl = r.clone();
    29. System.out.println(cl.getAge());//18
    30. System.out.println(cl.getName());//zz
    31. System.out.println(r==cl);//比较两个对象的地址值 false
    32. }
    33. }

    浅克隆案例

    三好学生奖状,奖状除了名字不同,其他均相同

    1. class Citation implements Cloneable{
    2. private String name;
    3. public String getName() {
    4. return name;
    5. }
    6. public void setName(String name) {
    7. this.name = name;
    8. }
    9. public void show(){
    10. System.out.println(name+"同学表现优异,特发此状!");
    11. }
    12. @Override
    13. public Citation clone() throws CloneNotSupportedException {
    14. return (Citation) super.clone();
    15. }
    16. }
    17. public class Client{
    18. public static void main(String[] args) throws CloneNotSupportedException {
    19. Citation citation = new Citation();
    20. Citation clone = citation.clone();
    21. citation.setName("张三");
    22. clone.setName("李四");
    23. citation.show();
    24. clone.show();
    25. }
    26. }

    深克隆

    1. class Citation implements Cloneable{
    2. private Student student;
    3. public Student getStudent() {
    4. return student;
    5. }
    6. public void setStudent(Student student) {
    7. this.student = student;
    8. }
    9. public void show(){
    10. System.out.println(student.getName()+"同学表现优异,特发此状!");
    11. }
    12. @Override
    13. public Citation clone() throws CloneNotSupportedException {
    14. return (Citation) super.clone();
    15. }
    16. }
    17. public class Client{
    18. public static void main(String[] args) throws CloneNotSupportedException {
    19. Citation citation = new Citation();
    20. Student student = new Student();
    21. student.setName("张三");
    22. citation.setStudent(student);
    23. Citation clone = citation.clone();
    24. Student student1 = clone.getStudent();
    25. student1.setName("李四");
    26. citation.show();
    27. clone.show();
    28. }
    29. }
    30. class Student{
    31. private String name;
    32. public String getName() {
    33. return name;
    34. }
    35. public void setName(String name) {
    36. this.name = name;
    37. }
    38. @Override
    39. public String toString() {
    40. return "Student{" +
    41. "name='" + name + '\'' +
    42. '}';
    43. }
    44. }

    浅克隆出现的问题

    当克隆类中有一个student类时,复制出来的Citation中的student和原citation的student是同一个,所以两个citation执行show方法时,都会打印李四的名字。

    深克隆需要使用对象流操作

    把奖状对象写到文件中或序列化到硬盘上,再读取对象,获取到的对象就是完全不同的对象。

    1. import java.io.*;
    2. class Citation implements Cloneable, Serializable {
    3. private Student student;
    4. public Student getStudent() {
    5. return student;
    6. }
    7. public void setStudent(Student student) {
    8. this.student = student;
    9. }
    10. public void show(){
    11. System.out.println(student.getName()+"同学表现优异,特发此状!");
    12. }
    13. @Override
    14. public Citation clone() throws CloneNotSupportedException {
    15. return (Citation) super.clone();
    16. }
    17. }
    18. public class Client{
    19. public static void main(String[] args) throws Exception {
    20. Citation citation = new Citation();
    21. Student student = new Student();
    22. student.setName("张三");
    23. citation.setStudent(student);
    24. //创建对象输出流对象
    25. ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("d:a.txt"));
    26. //写对象
    27. oos.writeObject(citation);
    28. //释放资源
    29. oos.close();
    30. //创建对象输入流对象
    31. ObjectInputStream ois = new ObjectInputStream(new FileInputStream("d:a.txt"));
    32. //读取对象
    33. Citation clone = (Citation) ois.readObject();
    34. //释放资源
    35. ois.close();
    36. Student student1 = clone.getStudent();
    37. student1.setName("李四");
    38. citation.show();
    39. clone.show();
    40. }
    41. }
    42. class Student implements Serializable{
    43. private String name;
    44. public String getName() {
    45. return name;
    46. }
    47. public void setName(String name) {
    48. this.name = name;
    49. }
    50. @Override
    51. public String toString() {
    52. return "Student{" +
    53. "name='" + name + '\'' +
    54. '}';
    55. }
    56. }

     Citation和Student类必须实现序列化接口

  • 相关阅读:
    港陆证券:服装家纺公司上半年投资并购力度加大
    使用pyttsx3实现简单tts服务
    uniapp原生插件开发实战——Android打开文件到自己的app
    苹果电脑pd工具箱Parallels Toolbox中文
    【Vue基础二】--- 计算属性,watch,style,class,条件列表渲染
    解决连接数据库提示:Public Key Retrieval is not allowed
    一键启停脚本
    [Kogel.Subscribe.Mssql]SQL Server增量订阅,数据库变更监听
    bert模型的参数量和时间复杂度分析
    spring bean 生命周期
  • 原文地址:https://blog.csdn.net/weixin_52972575/article/details/125622205