设计模式之原型模式!附Java代码示例!

大家好,欢迎来到程序视点 我是你们的老朋友.安戈。

今天,我们一起来分享创建型模式的最后一个模式:原型模式

定义

它的定义非常简单易懂。

用原型实例指定创建对象种类,并通过拷贝原型创建新的对象

通俗点的说法就是:照着原来的实例创建一个新对象 再通俗点:克隆一个对象实例

原型模式简介

上面关于原型模式定义已经说的很明白了。在含义上没有其他需要特别说明的。这里要注意的是Java中对这种模式的处理方式。

Java 中 Object 类是所有类的根类,Object 类提供了一个 clone 方法,该方法可以将一个 Java 对象复制一份,但是需要实现 clone 的 Java 类必须要实现一个接口 Cloneable,该接口表示该类能够复制且具有复制的能力

说了这么长一串,就是告诉大家:必须实现 Cloneable 接口原型模式里有哪些角色呢?

  • 抽象原型类。它负责定义用于复制现有实例来生成新实例的方法。碰巧Java中的 Cloneable 接口就可以表示它
  • 具体原型类。它就是负责实现复制或克隆现有实例的类

示例

来看看克隆羊的例子吧!

ini 复制代码
public class Sheep implements Cloneable {  
    private String name;  
    private Integer age;  
    private String color;  

    public Sheep(String name, Integer age, String color) {  
        this.name = name;  
        this.age = age;  
        this.color = color;  
    }  

   ... setter & getter  

    @Override  
    public String toString() {  
        return "Sheep{" +  
                "name='" + name + ''' +  
                ", age=" + age +  
                ", color='" + color + ''' +  
                '}';  
    }  

    @Override  
    protected Object clone() {  
        Sheep sheep = null;  
        try {  
            sheep = (Sheep) super.clone();  
        } catch (Exception e) {  
            e.printStackTrace();  
        }  
        return sheep;  
    }  
}  

测试下:

ini 复制代码
public class Test {  
    public static void main(String[] args) {  
        Sheep sheep = new Sheep("Tom", 1, "白色");  
        for (int i = 0; i < 10; i++) {  
            // 克隆了10只羊  
            Sheep sheep1 = (Sheep) sheep.clone();  
            System.out.println(sheep1);  
        }  
    }  
}  

这里要说明两个要点:

  • 克隆对象与原对象不是同一个对象,即sheep.clone() != sheep
  • 克隆对象与原对象的类型一样(原型-->原来的类型),即sheep.clone().getClass() == sheep.getClass()

深/浅拷贝问题

所谓浅拷贝,就是对象的成员属性是引用类型时,克隆后的新对象中的成员属性引用的依旧是原对象中成员属性的内存地址。也就是说:成员属性如果是引用类型,克隆的是内存地址;这个内存地址是不变的,指向的是同一个

如果对象的成员属性是基本数据类型,那默认就是值传递。也就是将该属性值复制一份给新的对象。上面克隆羊的例子就是浅拷贝。

PS:这里有个特殊的引用类型类--String。String没有实现Cloneable,但它是"不可变的",表现出来的是"深拷贝"的特性。

所谓深拷贝,就是复制对象的所有基本数据类型的成员变量值,同时为所有引用数据类型的成员变量申请存储空间,并复制每个引用数据类型成员变量所引用的对象。也就是说:全员复制

来个深拷贝的例子作为结尾。

java 复制代码
public class Shepherd implements Cloneable {  

    private String name;  
    private int age;  
    private Sheep sheep;  

    ... setter & getter  

    @Override  
    public Object clone() throws CloneNotSupportedException {  
        Shepherd shepherd = (Shepherd) super.clone();  
        // Sheep 需要实现 Cloneable, [强调]注意: Bag 这里只有基本数据类  
        // 如果要实现完全深拷贝, Shepherd类中只能含有非基本数据类型, 如果有非基本数据类, 那么在 sheep.clone()中必须再做一次类似的深拷贝复制  
        shepherd.setSheep((Sheep) this.sheep.clone());  
        return shepherd;  
    }  
}  

重点是 Shepherd 类中重写的 clone() 方法。Shepherd shepherd = (Shepherd) super.clone();完成的就是浅拷贝。此次的 shepherd 对象中的 sheep 成员属性还引用的是原对象中的 sheep 的内存地址。 好在我们的 Sheep 也实现了 Cloneable 类。克隆一份 sheep 对象赋值回去就达到深拷贝的效果了。于是就有shepherd.setSheep((Sheep) this.sheep.clone());

PS:关于深拷贝,可以细细体会下上面的这个示例。

最后

【程序视点】助力打工人减负,从不是说说而已!

如果你觉得这篇教程有帮助,别忘了【点赞+收藏+关注】三连支持!

后续安戈会持续分享更多开发工具和技巧,敬请期待!如果有其他工具需求,欢迎留言讨论~ 🚀

相关推荐
indexsunny4 小时前
互联网大厂Java求职面试实战:Spring Boot微服务与Redis缓存场景解析
java·spring boot·redis·缓存·微服务·消息队列·电商
无心水4 小时前
【分布式利器:腾讯TSF】7、TSF高级部署策略全解析:蓝绿/灰度发布落地+Jenkins CI/CD集成(Java微服务实战)
java·人工智能·分布式·ci/cd·微服务·jenkins·腾讯tsf
28岁青春痘老男孩9 小时前
JDK8+SpringBoot2.x 升级 JDK 17 + Spring Boot 3.x
java·spring boot
方璧9 小时前
限流的算法
java·开发语言
元Y亨H9 小时前
Nacos - 服务注册
java·微服务
曲莫终10 小时前
Java VarHandle全面详解:从入门到精通
java·开发语言
一心赚狗粮的宇叔10 小时前
中级软件开发工程师2025年度总结
java·大数据·oracle·c#
奋进的芋圆10 小时前
DataSyncManager 详解与 Spring Boot 迁移指南
java·spring boot·后端
计算机程序设计小李同学10 小时前
个人数据管理系统
java·vue.js·spring boot·后端·web安全
小途软件11 小时前
用于机器人电池电量预测的Sarsa强化学习混合集成方法
java·人工智能·pytorch·python·深度学习·语言模型