美文网首页
项目中频繁的数据转换我们怎么优化

项目中频繁的数据转换我们怎么优化

作者: rickJinzhu | 来源:发表于2020-01-16 09:07 被阅读0次

我们先来看一张数据扭转的图,这个是DDD思想下各种对象转换的过程。

VO(View Object):视图对象,用于展示层,它的作用是把某个指定页面(或组件)的所有数据封装起来。

DTO(Data Transfer Object):数据传输对象,用于展示层与服务层之间的数据传输对象。

DO(Domain Object):领域对象,就是从现实世界中抽象出来的有形或无形的业务实体。

PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。

VO层我们先不看,从DTO开始,我们梳理简单一个请求流程中数据会转换几次:

  • 请求时用户接口层DTO转DO
  • 请求时领域层DO转PO
  • 返回时领域层PO转DO
  • 返回是DO转DTO

我们先看下操作之前和操作之后的代码,在来详解:

    public static void main(String[] args) {
        //初始化对象
        UserDto userDto = new UserDto();
        userDto.setId(1);
        userDto.setName("java圈");
        ////////////////////////////
        //UserDto转成对象UserDo
        UserDtoToUserDo userDtoToUserDo = new UserDtoToUserDo();
        UserDo userDo = userDtoToUserDo.convert(userDto);
        //UserDo转成对象UserPo
        UserDoToUserPo userDoToUserPo = new UserDoToUserPo();
        UserPo userPo = userDoToUserPo.convert(userDo);
        //UserPo转成对象UserDo
        UserPoToUserDo userPoToUserDo = new UserPoToUserDo();
        UserDo userDo1 = userPoToUserDo.convert(userPo);
        //UserDo转成对象UserDto
        UserDoToUserDto userDoToUserDto = new UserDoToUserDto();
        UserDto userDto1 = userDoToUserDto.convert(userDo1);
        System.out.println("改造之前的结果:"+userDto1);

        ////////////////////////////
        UserDo userDo2 = AssemblerFactory.getInstance().execute(UserDtoToUserDoAssembler.class,userDto, UserDo.class);
        UserPo userPo1 = AssemblerFactory.getInstance().execute(UserDoToUserPoAssembler.class,userDo2, UserPo.class);
        UserDo userDo3 = AssemblerFactory.getInstance().execute(UserPoToUserDoAssembler.class,userPo1, UserDo.class);
        UserDto userDto2 = AssemblerFactory.getInstance().execute(UserDoToUserDtoAssembler.class,userDo3, UserDto.class);
        System.out.println("改造之后的结果:"+userDto2);

    }

这段代码用两种方式实现了上述的四个对象的转换:

第一种

  • 直接通过创建对象的方式进行数据扭转,可读性较差,容易混乱;
  • 创建流程较麻烦,需要创建8个对象,占用额外的内存空间
  • 可扩展性较差,牵一发而动全身;

第二种

  • 通过工厂模式+代码模式+单例模式设计思想去实现,符合SOLID原则;
  • 基于接口做实现代理,符合低耦合的概念;
  • 可读性较强,每一个转换只要一行代码,只要清楚转换类型、原始对象和目标对象

功能实现

接口定义

数据转换接口,里面有一个convert转换的方法,需要传入原始对象,和返回对象的类型,直接返回目标对象,便于代码规范化话和代码隔离。

public interface Assembler<R,T> {
    public T convert(R original,Class<T> targetType);
}

工厂类定义

AssemblerFactory是一个单例工厂,通过getAssembler传入的类型,获取目标转换对象的实例,ReflectionUtils为Spring-core里面的反射方法;execute执行实现类连的转换方法,需要传入原始对象和目标对象。

public class AssemblerFactory {
    private static AssemblerFactory INSTANCE = new AssemblerFactory();

    private AssemblerFactory(){}

    public static AssemblerFactory getInstance(){
        return INSTANCE;
    }

    private  Assembler getAssembler(Class type){
        Assembler assembler = null;
        try {
            assembler = (Assembler) ReflectionUtils.accessibleConstructor(type, new Class[0]).newInstance(new Object[0]);
        } catch (Throwable e){
            e.printStackTrace();
        }
        return assembler;
    }

    public <R,T> T execute(Class type,R original,Class<T> targetType){
        Assembler assembler = getAssembler(type);
        T target = (T) assembler.convert(original,targetType);
        return target;
    }
}

转换类实现

这里提供一个样例实现,实现接口Assembler,添加返回原始对象和目标对象,实现convert业务逻辑转换,这里有可能要问,里面转换的过程是否还可以优化?可以肯定是可以的,比如用组合模式,把DTO、VO、PO里面的字段进行封装、用组合+接口的方式实现,但是做起来还是比较麻烦。这里最好是建议用get/set方法转换,不要用一些序列化工具转换,执行效率没有get/set高。

/**
 * UserDo  转  UserDto
 */
public class UserDoToUserDtoAssembler implements Assembler<UserDo,UserDto>{
    @Override
    public UserDto convert(UserDo userDo,Class<UserDto> target){
        UserDto userDto = new UserDto();
        userDto.setId(userDo.getId());
        userDto.setName(userDo.getName());
        return userDto;
    }

}

源代码:https://github.com/itrickzhang/spring-demo/tree/master/data-conversion

本文由博客一文多发平台 OpenWrite 发布!

相关文章

  • 项目中频繁的数据转换我们怎么优化

    我们先来看一张数据扭转的图,这个是DDD思想下各种对象转换的过程。 VO(View Object):视图对象,用于...

  • Rxjava操作符学习(变换操作符)

    转换操作符在项目中使用是很频繁的,其原理也是最难的;不过一开始我们还是先知道怎么使用吧!转换操作符如下: Buff...

  • YYModel 性能优化

    YYModel 性能优化的几个 Tip: 缓存Model JSON 转换过程中需要很多类的元数据,如果数据足够小,...

  • 我的第一个硬件联调app 资料

    iOS蓝牙中的进制转换,数据格式转换 最近在忙一个蓝牙项目,在处理蓝牙数据的时候,经常遇到进制之间的转换,蓝牙处理...

  • iOS 项目依赖子模块工程

    上一节我们讲了项目结构优化中的《项目嵌套子工程》,接下来我们继续学习项目结构优化系列之项目依赖子模块工程。在开发中...

  • 无标题文章

    目录 笔记大型项目优化概述大型项目优化的方向代码优化数据库优化缓存优化架构优化Memcache与MySQL比较语法...

  • iOS性能优化相关知识(一)

    前言我们在面试中,经常会被问到一些问题,如:“你在项目中是怎么优化内存的?”“具体从哪几方面优化项目?”“遇到过t...

  • 使用 BasicMessageChannel 处理 flutte

    引言 最近碰到个需求,需要在flutter层频繁的调用原生层进行数据转换。我们之前使用 MethodChannel...

  • ListView性能优化

    ListView实在是使用的太频繁了,记录下ListView怎么在项目中去优化卡顿现象。首先想到的就是,这些是最基...

  • 如何用ThinkPHP里的模型方式对数据进行假删除(软删除)

    在我们实际使用ThinkPHP的工作和项目开发中,对数据库频繁的操作,删除数据,会导致用户体验性很差的问题,利用模...

网友评论

      本文标题:项目中频繁的数据转换我们怎么优化

      本文链接:https://www.haomeiwen.com/subject/oatfzctx.html