• 【设计模式】原型模式


    原型模式

    1.什么是原型模式

    • 原型设计模式简单来说就是克隆

    • 原型表明了有一个样板实例,这个原型是可定制的。原型模式多用于创建复杂的或者构造耗时的实例,因为这种情况下,复制一个已经存在的实例可使程序运行更高效

    2.原型模式的应用场景

    1. 类初始化需要消化非常多的资源,这个资源包括数据、硬件资源等。这时我们就可以通过原型拷贝避免这些消耗。
    2. 通过new产生的一个对象需要非常繁琐的数据准备或者权限,这时可以使用原型模式。
    3. 一个对象需要提供给其他对象访问,而且各个调用者可能都需要修改其值时,可以考虑使用原型模式拷贝多个对象供调用者使用,即保护性拷贝。

    我们Spring框架中的多例就是使用原型。

    3.原型模式的使用方式

    1. 实现Cloneable接口。在java语言有一个Cloneable接口,它的作用只有一个,就是在运行时通知虚拟机可以安全地在实现了此接口的类上使用clone方法。在java虚拟机中,只有实现了这个接口的类才可以被拷贝,否则在运行时会抛出CloneNotSupportedException异常。

    2. 重写Object类中的clone方法。Java中,所有类的父类都是Object类,Object类中有一个clone方法,作用是返回对象的一个拷贝,但是其作用域protected类型的,一般的类无法调用,因此Prototype类需要将clone方法的作用域修改为public类型。

    3.1原型模式分为浅复制和深复制
    • (浅复制)只是拷贝了基本类型的数据,而引用类型数据,只是拷贝了一份引用地址。

    • (深复制)在计算机中开辟了一块新的内存地址用于存放复制的对象。

    4.代码演示

    1. 创建User类
    package com.lijie;
    
    import java.util.ArrayList;
    
    public class User implements Cloneable {
        private String name;
        private String password;
        private ArrayList<String> phones;
    
        protected User clone() {
            try {
                User user = (User) super.clone();
                //重点,如果要连带引用类型一起复制,需要添加底下一条代码,如果不加就对于是复制了引用地址
                user.phones = (ArrayList<String>) this.phones.clone();//设置深复制
                return user;
            } catch (CloneNotSupportedException e) {
                e.printStackTrace();
            }
            return null;
        }
    	
    	//省略所有属性Git Set方法......
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    1. 测试复制
    package com.lijie;
    
    import java.util.ArrayList;
    
    public class Client {
        public static void main(String[] args) {
            //创建User原型对象
            User user = new User();
            user.setName("李三");
            user.setPassword("123456");
            ArrayList<String> phones = new ArrayList<>();
            phones.add("17674553302");
            user.setPhones(phones);
    
            //copy一个user对象,并且对象的属性
            User user2 = user.clone();
            user2.setPassword("654321");
    
            //查看俩个对象是否是一个
            System.out.println(user == user2);
    
            //查看属性内容
            System.out.println(user.getName() + " | " + user2.getName());
            System.out.println(user.getPassword() + " | " + user2.getPassword());
            //查看对于引用类型拷贝
            System.out.println(user.getPhones() == user2.getPhones());
        }
    }
    
    
    • 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
    1. 如果不需要深复制,需要删除User 中的
    //默认引用类型为浅复制,这是设置了深复制
    user.phones = (ArrayList<String>) this.phones.clone();
    
    
    • 1
    • 2
    • 3
  • 相关阅读:
    垃圾回收机制
    【Golang】判断某一类型是否实现指定接口的几种方法
    「Python实用秘技11」在Python中利用ItsDangerous快捷实现数据加密
    CPU的亲缘性affinity
    编程命名方法
    如何分析判断一篇文章是不是chatgpt写的
    数据结构学习笔记——交换排序(冒泡排序和快速排序)
    千峰课程网安笔记(1)
    手撕前端面试题(Javascript~事件委托、数组去重、合法的URL、快速排序、js中哪些操作会造成内存泄漏......
    深度学习模型理解-CNN-手写数据字代码
  • 原文地址:https://blog.csdn.net/df007df/article/details/133991056