• Java设计模式之原型模式


    1. 原型模式

    1.1 原型模式的定义、优缺点、应用场景

    定义:用一个已经创建的实例对象作为原型,通过复制该原型对象来创建一个和原型对象相同或相似的新对象。避免了重复执行耗时耗资源的new构造函数过程

    优点

    • Java自带的原型模式(implements Cloneable,然后override clone方法)基于内存二进制流的复制,在性能上比直接new一个对象更加优良

    缺点

    • 需要为类配置一个clone方法
    • clone方法位于类的内部,当对已有类进行改造的时候,需要修改代码,违背了开闭原则
    • 当实现深克隆时,如果类的属性是一个Object,则需要对该Object进行复制。且该Object对应的类也需要实现深克隆。如此递归下去,实现很麻烦

    应用场景

    • 对象之间相同或相似,即只是个别的几个属性不同的时候
    • 创建对象成本较大,例如初始化时间长,占用CPU太多,或者占用网络资源太多等,需要优化资源
    • 创建一个对象需要繁琐的数据准备或访问权限等,需要提高性能或者提高安全性
    • 系统中大量使用该类对象,且各个调用者都需要给它的属性重新赋值

    1.2 原型模式的结构与实现

    结构

    • 具体原型类:实现Cloneable接口并override clone方法
    • 通过具体原型类实例化一个对象,然后调用该对象的clone方法复制出新对象

    浅克隆和深克隆

    • 浅克隆:创建一个新对象,新对象的属性和原来对象的属性完全相同,因为对象的属性指向的是同一个内存地址
    • 深克隆:创建一个新对象,新对象的属性(非基本类型属性)也被克隆

    示例如下

    public class PrototypeTest {
    
        public static void main(String[] args) {
    
            Prototype prototype1 = new Prototype("zhang_san", new DeepClone());
            Prototype prototype2 = (Prototype) prototype1.clone();
            System.out.println("prototype1和prototype2的内存地址是否一样:" + (prototype1 == prototype2));
            prototype2.setName("li_si");
    
        }
    }
    
    // 用于实现深克隆
    class DeepClone implements Cloneable {
    
        public DeepClone() {
    
        }
    
        public Object clone() {
    
            DeepClone deepClone = null;
            try {
                deepClone = (DeepClone) super.clone();
            } catch (CloneNotSupportedException e) {
            }
            return deepClone;
        }
    
    }
    
    // 具体原型类
    class Prototype implements Cloneable {
    
        private String name;
        private DeepClone deepClone;
    
        public Prototype(String name, DeepClone deepClone) {
            this.name = name;
            this.deepClone = deepClone;
            System.out.println("原型对象创建成功");
        }
    
        public String getName() {
            return this.name;
        }
    
        // 用于对复制的新对象修改属性。实现相似对象的复制功能
        public void setName(String name) {
            this.name = name;
        }
    
        public DeepClone getDeepClone() {
            return this.deepClone;
        }
    
        public void setDeepClone(DeepClone deepClone) {
            this.deepClone = deepClone;
        }
    
    
        public Object clone() {
    
            Prototype prototype = null;
            try {
                // 实现浅克隆
                prototype = (Prototype) super.clone();
                // 实现深克隆
                prototype.deepClone = (DeepClone) prototype.deepClone.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println("原型对象复制失败");
            }
            System.out.println("原型对象复制成功");
            return prototype;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76

    运行程序,结果如下:

    原型对象创建成功
    原型对象复制成功
    prototype1和prototype2的内存地址是否一样:false
    
    • 1
    • 2
    • 3
  • 相关阅读:
    数字藏品平台常见的活动玩法
    Spring Boot自动配置
    停车场防逃费设备有哪些,捷曜超眸相机怎么样,有哪些功能?
    RabbitMQ系列【1】概述
    竞赛 基于深度学习的人脸专注度检测计算系统 - opencv python cnn
    Go | 闭包的使用
    国产大模型各自优势如何?大家都怎么选?
    【2023研电赛】兆易创新命题三等奖: 低成本单母线电流永磁同步无感驱动器
    ubuntu 20.04 SD 卡分区类型 msdos 改为 GPT 的方法
    第10讲:DQL数据查询语句之LIMIT分页查询示例
  • 原文地址:https://blog.csdn.net/yy8623977/article/details/126404659