工作中的设计模式 —— 原型模式

人工智能
• 阅读 1059

前言

原型模式是一种创建型设计模式, 使你能够复制已有对象, 而又无需使代码依赖它们所属的类。

通俗说法,就是将一个类作为原型,然后复制出来另一个类。

使用场景

这么一说,是不是发现我们经常使用?

比如咱们项目中有 BO、DTO、VO,但是在开发过程中,需要各种转换,get/set,一般情况下大家都会使用 BeanUtils,将一个类的属性值 set 到另一个类的属性值中,然后返回。

当然,也有一个实体直接从头捅到尾的。

关于 BeanUtils 的 copy 方法,各个框架都提供了相关工具,不过 Java 开发手册 有指出 Apache BeanUtils 性能较差、也推荐了其他框架。

工作中的设计模式 —— 原型模式

这里介绍的是使用 Cglib BeanCopier。

封装工具类

查看文档,先封装一个工具类:

public class BeanCopierUtils {

    private BeanCopierUtils() {
    }

    /**
     * 将source对象的属性拷贝到target对象中去
     *
     * @param source source对象
     * @param target target对象
     */
    public static void copyProperties(Object source, Object target) {

        BeanCopier beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);

        beanCopier.copy(source, target, null);
    }
}

看到这里是不是感觉,如果我使用 BeanCopier 比较频繁,然后每次都 create 创建对象,是不是很麻烦?

所以就想到需要用缓存!

将 BeanCopier 作为一个,在各个线程使用的时候,共享。

public class BeanCopierUtils {

    private BeanCopierUtils() {
    }

    /**
     * BeanCopier缓存
     */
    private static Map<String, BeanCopier> CACHE = new HashMap<>();

    /**
     * 将source对象的属性拷贝到target对象中去
     *
     * @param source source对象
     * @param target target对象
     */
    public static void copyProperties(Object source, Object target) {
        String cacheKey = source.getClass().getName() + target.getClass().getName();

        BeanCopier beanCopier;

        if (!CACHE.containsKey(cacheKey)) {
            // 进入到这里会创建一个BeanCopier实例并且放在缓存map中
            beanCopier = BeanCopier.create(source.getClass(), target.getClass(), false);
            CACHE.put(cacheKey, beanCopier);
        } else {
            beanCopier = CACHE.get(cacheKey);
        }

        beanCopier.copy(source, target, null);
    }
}

然后再代码中就可以欢快的使用啦!

BeanCopierUtils.copyProperties(dto, vo);

到这里,大家发现,好像就封装了一个工具类,和原型模式并没有什么关系啊。

对象的 clone

到此其实在代码中都可以使用了,不过还是要在 DTO、VO 中声明 clone 方法,这样之后使用才会更方便~

/**
 * 将当前对象转化为目标对象
 *
 * @param clazz
 * @param <T>
 * @return
 * @throws Exception
 */
public <T> T clone(Class<T> clazz) throws Exception {

    T target = clazz.newInstance();
    BeanCopierUtils.copyProperties(this, target);
    return target;
}

现在使用的时候就可以

AccountVO accountVO = accountDTO.clone(AccountVO.class);

不过也是有弊端的,比如这里使用的是泛型,我明明是 UserVO 要 Clone , 你非得传一个 AddressDTO,那我也没得办法了。

至于进一步演化,可以将 clone 抽象到公共方法中,比如给所有 DTO 创建一个 BaseDTO。

还有深拷贝这块,也需要注意。

总结

其实工作中有很多设计模式,只不过用到了,大家没有发现。

当然工作中使用的时候,都是一切为了敏捷,可能并没有定义什么 Prototype 接口之类的,但是还是要多总结。

最后,小伙伴们工作中,有使用什么设计模式,以及实际中的应用场景,欢迎留言分享。

相关资料

  1. 《深入设计模式》:https://refactoringguru.cn/design-patterns
  2. 封面图:https://refactoringguru.cn/design-patterns/prototype
点赞
收藏
评论区
推荐文章
灯灯灯灯 灯灯灯灯
4年前
「超全超细」Java设计模式图文详解!!!
java设计模式—原型模式Java原型模式1、概述  啥是原型模式?  原型模式属于设计模式中的创建型中的一员,  原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象!  说大白话就是自己复制自己,通过原生对象复制出一个新的对象,这两个对象结构相同且相似;  需要注意的是,原型对象自己不仅是个对象还是个工厂!并且通过克隆方式创
Stella981 Stella981
3年前
JavaScript面向对象编程的15种设计模式
在程序设计中有很多实用的设计模式,而其中大部分语言的实现都是基于“类”。在JavaScript中并没有类这种概念,面向对象编程不是基于类,而是基于原型去面向对象编程,JS中的函数属于一等对象,而基于JS中闭包与弱类型等特性,在实现一些设计模式的方式上与众不同。ps:本文之讲述面向对象编程的设计模式策略,JavaScript原型的基础请参考阮一峰面向
Wesley13 Wesley13
3年前
PHP设计模式之模板方法模式
PHP设计模式之模板方法模式模板方法模式,也是我们经常会在不经意间有会用到的模式之一。这个模式是对继承的最好诠释。当子类中有重复的动作时,将他们提取出来,放在父类中进行统一的处理,这就是模板方法模式的最简单通俗的解释。就像我们平时做项目,每次的项目流程实都差不多,都有调研、开发、测试、部署上线等流程。而具体到每个项目中,这些
Wesley13 Wesley13
3年前
Java 设计模式
前言23种经典的模式,根据用途我们又可以分为三大类,分别为创建型模式、结构型模式和行为型模式。创建型模式创建型模式的作用就是创建对象,说到创建一个对象,最熟悉的就是new一个对象,然后set相关属性。但是,在很多场景下,我们需要给客户端提供更加友好的创建对象的方式,尤其是那种我们定义了类,但是需要提供给其他开发者用的时
Wesley13 Wesley13
3年前
Java中23种设计模式详解
Java中23种设计模式1\.设计模式31.1创建型模式41.1.1工厂方法41.1.2抽象工厂61.1.3建造者模式101.1.4单态模式131.1.5原型模式151.2结构型模式171.2.1适配器模式171.2.2桥接模式191.2.3组合
Wesley13 Wesley13
3年前
Java设计模式之原型模式
原型模式简介原型模式实际上不算一种设计模式,应该说是一种技巧吧。当我们需要创建与已有对象一样的对象时,我们通常可以有两种容易想到的方法,一种是将已有对象指向另外一个重新创建的对象,如//将old赋给newObjectnewObjectoldObject;这种做法是相当于newObject还是指向
Wesley13 Wesley13
3年前
Java原型模式
原型模式  原型模式也称克隆模式。原型模式jianmingzhiyi,就是先创造出一个原型,然后通过类似于Java中的clone方法,对对象的拷贝,克隆类似于new,但是不同于new。new创造出来的对象采用的是默认值。克隆出来的对象与原型对象相同,同时不会影响原型对象,然后在修改克隆出来的对象。实现  继承Cloneable接口,重写cl
Wesley13 Wesley13
3年前
23种设计模式(面向对象语言)
一、设计模式的分类总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。创建型模式是用来创建对象的模式,抽象了实例化的过程,帮助一个系统独立于其他关联对象的创建、组合和表示方式。所有的创建型模式都有两个主要功能:  1.将系统所使用的具体类的信息封装起来  2.隐藏
Wesley13 Wesley13
3年前
JS创建对象模式7种方法详解
创建对象的几种模式虽然Object构造函数或者字面量,都可以用来创建对象,但这些方式有明显的缺点:使用同一个接口创建很多对象,会产生大量的代码,于是,工厂模式诞生了1工厂模式工厂模式是广为人知的设计模式,抽象了创建具体对象的过程。在ES6的Class创建类之前,是无法创建类的,开发人员就发明了一种函数,用函数来封
Wesley13 Wesley13
3年前
C++ 常用设计模式(学习笔记)
设计模式1、工厂模式在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。1.1、简单工厂模式主要特点是需要在工厂类中做判断,从而创造相应的产品,当
设计模式-单例模式概述 | 京东云技术团队
我们常把23种经典的设计模式分为三类:创建型、结构型、行为型,其中创建型设计模式主要解决“对象的创建”问题,将创建和使用代码解耦,结构型设计模式主要解决“类或对象的组合或组装”问题,将不同功能代码解耦,行为型设计模式主要解决“类或对象之间的交互”问题,将不