ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Spring中常见的设计模式——原型模式

2020-07-02 13:35:43  阅读:304  来源: 互联网

标签:UserDto dto 克隆 Spring 原型 user new 设计模式 public


1、原型模式应用场景

  当遇到大量耗费劳动力的 get,set赋值场景时,如下:

复制代码
public class SetGetParam {
    public void setParam(UserDto userDto) {
        User user = new User();
        user.setAge(userDto.getAge());
        //...
     userDao.addUser(user); } }
复制代码

  原型模式(Prototype pattern)是指原型实例指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模式主要适用于以下:

  (1)类初始化消耗资源较多;

  (2)使用new 生成一个对象需要非常繁琐的过程(数据准备访问权限等);

  (3)构造函数比较复杂;

  (4)在循环体中产生大量对象;

  在spring中用到的原型模式有:scope="prototype" ,还有常用的JSON.parseObject()也是一种原型模式

2、浅克隆

  创建具体需要克隆的类:

复制代码
@Data
public class User {
    private String name;

    private Integer age;

    private List<String> hobbies;

    public UserDto clone() {
        UserDto dto = new UserDto();
        dto.setAge(this.age);
        dto.setName(this.name);
        dto.setHobbies(this.hobbies);
        return dto;
    }
}
复制代码

  创建Client:

复制代码
public class Client {
    private User user;

    public Client(User user) {
        this.user = user;
    }

    public UserDto startClone(User user) {
        return user.clone();
    }
}
复制代码

  测试克隆,对比复制过来的值是否有自己的地址,还是用的原来的地址

复制代码
public class PrototypeTest {
    public static void main(String[] args) {
        //创建具体需要克隆的对象
        User user = new User();
        user.setName("皮肤黝黑的小白");
        user.setHobbies(new ArrayList<>());
        System.out.println(user);
        //创建Client对象,准备开始克隆
        Client client = new Client(user);
        UserDto dto = client.startClone(user);
        System.out.println(dto);
        System.out.println(user.getHobbies() == dto.getHobbies());
        System.out.println(user.getName() == dto.getName());
    }
}
复制代码

  结果:

User(name=皮肤黝黑的小白, age=null, hobbies=[])
UserDto(name=皮肤黝黑的小白, age=null, hobbies=[])
true
true

  从测试结果可以看出:hobbies和name的内存地址是相同的,这说明我们并没有重新创建对象,这就是浅克隆。

3、深克隆

  采用序列化反序列化克隆,实现深克隆,

复制代码
@Data
public class UserDeepClone implements Cloneable {
    private String name;

    private Integer age;

    private List<String> hobbies;

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return this.deepClone();
    }

    public UserDto deepClone() {
        try {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos);
            oos.writeObject(this);

            ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bis);
            UserDto dto = (UserDto) ois.readObject();
            return dto;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
复制代码 复制代码
public class DeepCloneTest {
    public static void main(String[] args) {
        DeepCloneTest deepCloneTest = new DeepCloneTest();
        UserDeepClone user = new UserDeepClone();
        user.setName("皮肤黝黑的小白");
        user.setHobbies(new ArrayList<>());
        System.out.println(user);
        UserDto dto = null;
        try {
            dto = (UserDto) deepCloneTest.clone();
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }
        System.out.println(dto);
        System.out.println(user.getName() == dto.getName());
        System.out.println(user.getHobbies() == dto.getHobbies());
    }
}
复制代码

4、克隆破坏单例

  深克隆会破坏单例,其实防御方式很简单,单例类不要实现Cloneable接口即可。

5、ArrayList中clone()方法的源码

复制代码
    public Object clone() {
        try {
            ArrayList<?> v = (ArrayList<?>) super.clone();
            v.elementData = Arrays.copyOf(elementData, size);
            v.modCount = 0;
            return v;
        } catch (CloneNotSupportedException e) {
            // this shouldn't happen, since we are Cloneable
            throw new InternalError(e);
        }
    }
复制代码

转载于:https://www.cnblogs.com/xcgShare/p/11961799.html

标签:UserDto,dto,克隆,Spring,原型,user,new,设计模式,public
来源: https://www.cnblogs.com/it-deepinmind/p/13224179.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有