Spring中常见的设计模式——原型模式
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);
- }
- }
Spring中常见的设计模式——原型模式的更多相关文章
- Spring中常见的设计模式——代理模式
一.代理模式的应用场景 生活中的中介,黄牛,等一系列帮助甲方做事的行为,都是代理模式的体现.代理模式(Proxy Pattern)是指为题对象提供一种代理,以控制对这个对象的访问.代理对象在客户端和目 ...
- Spring中常见的设计模式——策略模式
策略模式(Strategy Pattern) 一.策略模式的应用场景 策略模式的应用场景如下: 系统中有很多类,而他们的区别仅仅在于行为不同. 一个系统需要动态的在集中算法中选择一种 二.用策略模式实 ...
- Spring中常见的设计模式——委派模式
一.委派模式的定义及应用场景 委派模式(Delegate Pattern)的基本作用是负责任务的调用和分配,跟代理模式很像,可以看做特殊情况下的静态的全权代理,但是代理模式注重过程,而委派模式注重结果 ...
- Spring中常见的设计模式——工厂模式
一.简单工厂模式 简单工厂模式(Simple Factory Pattern)由一个工厂对象决定创建哪一种产品类的实例,简单工厂模式适用于工厂类负责创建对象较少的情况,且客户端只需要传入工厂类的参数, ...
- Spring中常见的设计模式——模板模式
一.模板模式的应用场景 模板模式又叫模板方法模式(Template Method Pattern),指定义一个算法的骨架,并允许自雷为一个或者多个步骤提供实现.模板模式使得子类可以在不改变算法结果的情 ...
- Spring中常见的设计模式——适配器模式
一.适配器模式的应用场景 适配器模式(Adapter Pattern)是指将一个类的接口转换成用户期待的另一个接口,使原本接口不兼容的类可以一起工作,属于构造设计模式. 适配器适用于以下几种业务场景: ...
- 设计模式:JDK和Spring中常见的设计模式
设计模式 总结 类 工厂模式 封装创建过程,只对结果负责 BeanFactory.Calender 单例模式 全局唯一 ApplicationContext.Calender 原型模式 多重影分身之术 ...
- Spring中常见的设计模式——单例模式
一.单例模式的应用场景 单例模式(singleton Pattern)是指确保一个类在任何情况下都绝对只有一个实例,并提供一个全局访问点.J2EE中的ServletContext,ServletCon ...
- spring 中常用的设计模式
一. Spring 中常见的设计模式 工厂模式 : BeanFactory 装饰器模式: BeanWrapper 代理模式: AopProxy 单例模式: ApplicationContext 委派模 ...
随机推荐
- 【朝花夕拾】跨进程通信,你只知道AIDL,就OUT了
一.前言 提起跨进程通信,大多数人首先会想到AIDL.我们知道,用AIDL来实现跨进程通信,需要在客户端和服务端都添加上aidl文件,并在服务端的Service中实现aidl对应的接口.如果还需要服务 ...
- Java IO编程——字符流与字节流
在java.io包里面File类是唯一 一个与文件本身有关的程序处理类,但是File只能够操作文件本身而不能够操作文件的内容,或者说在实际的开发之中IO操作的核心意义在于:输入与输出操作.而对于程序而 ...
- java里的单例实现
枚举实现单例 线程安全,调用效率高,不能延时加载,可以天然的防止反射和反序列化调用 public enum SingletonFactory { //枚举元素本身就是单例 INSTANCE; //添加 ...
- Vue中Form表单验证无法消除验证问题
iView的表单api给出了一个resetFields方法,用于重置整个表单输入的内容并清除验证提示. 但是有时候需要只消除部分的iview的resetFields方法源码是这样的resetField ...
- 【原创】基于.NET的轻量级高性能 ORM - TZM.XFramework 之优雅增删改
[前言] 大家好,我是TANZAME.出乎意料的,我们在立冬的前一天又见面了,天气慢慢转凉,朋友们注意添衣保暖,愉快撸码.距离 TZM.XFramework 的首秀已数月有余,期间收到不少朋友的鼓励. ...
- 超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本
超简单让.NET Core开发者快速拥有CI/CD的能力-Docker版本 前言 上一篇自动化测试,全面且详细的介绍了从零开始到发布版本的步骤,这是传统的方式,本次为大家带来的是如何在5分钟内使用上d ...
- Knative Serving 健康检查机制分析
作者| 阿里云智能事业群技术专家牛秋霖(冬岛) 导读:从头开发一个Serverless引擎并不是一件容易的事情,今天咱们就从Knative的健康检查说起.通过健康检查这一个点来看看Serverles ...
- 学习笔记42_SpringMVC
SpringMVC中,Global.axas发生变化,其中 1.原来是 public class MvcApplication:System.web.HttpApplication 现在是 publi ...
- [python]一些常用的python知识总结
Pthon知识积累,遇到的各种python问题汇总 json.dumps()和json.loads()是json格式处理函数 json.dumps()函数是将一个Python数据类型列表进行json格 ...
- [Luogu5384][Cnoi2019] 雪松果树
传送门 虽然这题是一道二合一,也不算难,但还是学到了很多东西啊,\(k\) 级儿子个数的五种求法!!我还是觉得四种比较好( \(k\) 级儿子个数有五种求法,你知道么? --鲁迅 首先 \(k\) 级 ...