在日常编码中,我们会遇到这样一个场景:把一个类型的对象转换成另一个对象,而这两者之前的转换强调的是"值(Value)"的等价转换,两者之间并没有继承与被继承的关系,也并不是像浮点数转整数这种语法意义上的转换关系。如下面举的这个例子:"用户"这个对象定义了User和UserDto两种Bean class来表示,二者所代表的"值"都是一致的,只是一个是业务逻辑层面的,一个是数据访问层面的。二者之前常常会发生转换,这个时候可以使用转换器模式:

类图:

代码:

/*** User class*/
public class User {private String firstName;private String lastName;private boolean isActive;private String userId;/*** @param firstName user's first name* @param lastName  user's last name* @param isActive  flag indicating whether the user is active* @param userId user's identificator*/public User(String firstName, String lastName, boolean isActive, String userId) {this.firstName = firstName;this.lastName = lastName;this.isActive = isActive;this.userId = userId;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public boolean isActive() {return isActive;}public String getUserId() {return userId;}@Override public boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}User user = (User) o;return isActive == user.isActive && Objects.equals(firstName, user.firstName) && Objects.equals(lastName, user.lastName) && Objects.equals(userId, user.userId);}@Override public int hashCode() {return Objects.hash(firstName, lastName, isActive, userId);}@Override public String toString() {return "User{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\''+ ", isActive=" + isActive + ", userId='" + userId + '\'' + '}';}
}
/*** User DTO class*/
public class UserDto {private String firstName;private String lastName;private boolean isActive;private String email;/*** @param firstName user's first name* @param lastName  user's last name* @param isActive  flag indicating whether the user is active* @param email     user's email address*/public UserDto(String firstName, String lastName, boolean isActive, String email) {this.firstName = firstName;this.lastName = lastName;this.isActive = isActive;this.email = email;}public String getFirstName() {return firstName;}public String getLastName() {return lastName;}public boolean isActive() {return isActive;}public String getEmail() {return email;}@Override public boolean equals(Object o) {if (this == o) {return true;}if (o == null || getClass() != o.getClass()) {return false;}UserDto userDto = (UserDto) o;return isActive == userDto.isActive && Objects.equals(firstName, userDto.firstName) && Objects.equals(lastName, userDto.lastName) && Objects.equals(email, userDto.email);}@Override public int hashCode() {return Objects.hash(firstName, lastName, isActive, email);}@Override public String toString() {return "UserDto{" + "firstName='" + firstName + '\'' + ", lastName='" + lastName + '\''+ ", isActive=" + isActive + ", email='" + email + '\'' + '}';}
}
/*** Generic converter, thanks to Java8 features not only provides a way of generic bidirectional* conversion between coresponding types, but also a common way of converting a collection of objects* of the same type, reducing boilerplate code to the absolute minimum.* @param <T> DTO representation's type* @param <U> Domain representation's type*/
public class Converter<T, U> {private final Function<T, U> fromDto;private final Function<U, T> fromEntity;/*** @param fromDto Function that converts given dto entity into the domain entity.* @param fromEntity Function that converts given domain entity into the dto entity.*/public Converter(final Function<T, U> fromDto, final Function<U, T> fromEntity) {this.fromDto = fromDto;this.fromEntity = fromEntity;}/*** @param userDto DTO entity* @return The domain representation - the result of the converting function application on dto entity.*/public final U convertFromDto(final T userDto) {return fromDto.apply(userDto);}/*** @param user domain entity* @return The DTO representation - the result of the converting function application on domain entity.*/public final T convertFromEntity(final U user) {return fromEntity.apply(user);}/*** @param dtoUsers collection of DTO entities* @return List of domain representation of provided entities retrieved by*        mapping each of them with the convertion function*/public final List<U> createFromDtos(final Collection<T> dtoUsers) {return dtoUsers.stream().map(this::convertFromDto).collect(Collectors.toList());}/*** @param users collection of domain entities* @return List of domain representation of provided entities retrieved by*        mapping each of them with the convertion function*/public final List<T> createFromEntities(final Collection<U> users) {return users.stream().map(this::convertFromEntity).collect(Collectors.toList());}}
/*** Example implementation of the simple User converter.*/
public class UserConverter extends Converter<UserDto, User> {/*** Constructor.*/public UserConverter() {super(userDto -> new User(userDto.getFirstName(), userDto.getLastName(), userDto.isActive(),userDto.getEmail()),user -> new UserDto(user.getFirstName(), user.getLastName(), user.isActive(),user.getUserId()));}
}
/*** The Converter pattern is a behavioral design pattern which allows a common way of bidirectional* conversion between corresponding types (e.g. DTO and domain representations of the logically* isomorphic types). Moreover, the pattern introduces a common way of converting a collection of* objects between types.*/
public class App {/*** Program entry point** @param args command line args*/public static void main(String[] args) {Converter<UserDto, User> userConverter = new Converter<>(userDto -> new User(userDto.getFirstName(), userDto.getLastName(), userDto.isActive(),userDto.getEmail()),user -> new UserDto(user.getFirstName(), user.getLastName(), user.isActive(), user.getUserId()));UserDto dtoUser = new UserDto("John", "Doe", true, "whatever[at]wherever.com");User user = userConverter.convertFromDto(dtoUser);System.out.println("Entity converted from DTO:" + user);ArrayList<User> users = Lists.newArrayList(new User("Camile", "Tough", false, "124sad"),new User("Marti", "Luther", true, "42309fd"), new User("Kate", "Smith", true, "if0243"));System.out.println("Domain entities:");users.forEach(System.out::println);System.out.println("DTO entities converted from domain:");List<UserDto> dtoEntities = userConverter.createFromEntities(users);dtoEntities.forEach(System.out::println);}
}

转换器(Converter)模式相关推荐

  1. SpringMVC配置任何类型转换器 Converter(以时间类型为例)

    SpringMVC配置任何类型转换器 Converter (以时间类型为例) 从页面传到后台的时间字符串转成日期格式封装到实体类 1. 定义时间DateConverter转换类实现  Converte ...

  2. 转换器(Converter)—Struts 2.0中的魔术师

    本系列文章导航 为Struts 2.0做好准备 Struts 2的基石--拦截器(Interceptor) 常用的Struts 2.0的标志(Tag)介绍 在Struts 2.0中国际化(i18n)您 ...

  3. Spring MVC自定义类型转换器Converter、参数解析器HandlerMethodArgumentResolver

    文章目录 一.前言 二.类型转换器Converter 1.自定义类型转换器 三.参数解析器 1.自定义分页参数解析器 2.自定义注解参数解析器 一.前言 Spring MVC源码分析相关文章已出: S ...

  4. html5单位转换器,Converter单位转换器

    Converter单位转换器是一个功能强大且易于使用的应用程序,转换所有您所需.Converter支持超过650部来自35个不同的类别,欢迎大家前来下载体验. 产品特点: ★简单易用且非常直观的用户界 ...

  5. java converter转换器_在SpringMVC中设置自定义类型转换器Converter

    前言 在SpringMVC中为我们提供了许多内置的类型转换器,当我们在HTML表单中发起一个请求时,Spring会根据表单项中name属性的值映射到POJO的属性名,调用相对性属性的set方法帮我们把 ...

  6. SpringMVC(7)——类型转换器Converter

    目录 概述 内置的类型转换器 自定义类型转换器 创建实体类 创建控制器类 创建自定义类型转换器类 注册类型转换器 创建JSP视图文件 运行效果 概述 SpringMVC框架的Converter< ...

  7. EasyExcel 自定义LocalDate类型转换器Converter

    1 Maven依赖 <dependency><groupId>com.alibaba</groupId><artifactId>easyexcel< ...

  8. EasyExcel导入excel中时间格式到LocalDateTime字段转换器Converter

    项目开发中,Excel导入导出一直是比较重要并且常见的一个功能,之前在项目开发中一直使用的是Apache poi,最近发现alibaba推出的一个框架Easy Excel ,官网地址:EasyExce ...

  9. 【wpf】转换器 Converter

    今天积攒了一个转换器的用法,分享给各位. 我们经常会有这种需求: 某些控件有时需要显示,有时需要隐藏,比如: 那,我就想通过一个bool变量和是否显示绑定. 但是我们知道,是否显示,这个属性 Visi ...

最新文章

  1. 大厂面试篇:五轮面试,阿里offer到手!
  2. Codeforces1142D
  3. 前端学习(687):for循环执行流程
  4. matlab aviobj,MATLAB AVI 视频读取处理
  5. emlog和typecho文章采集插件-简数第三方数据采集
  6. mysql数据索引失效_MySQL索引失效的几种情况
  7. nginx 配置路由
  8. Redis性能问题排查解决手册(七)
  9. c++ string 末尾追加char字符
  10. @Html.DisplayFor 和 @mode.Display
  11. idea打包Jar包
  12. lpush和rpush的区别_redis数据类型之list-lpush,rpush讲解
  13. 标量与向量乘积求导法则
  14. cf-645D. Robot Rapping Results Report(拓扑序列)
  15. 乐富支付:互联网金融下的民企新生态
  16. 小程序 设置小程序打开聊天中的素材
  17. android界面UI美化:沉浸模式、全透明或半透明状态栏及导航栏的实现
  18. linux 有名管道(FIFO)
  19. vue upload上传图片
  20. vSphere 虚拟化基础概念讲解与环境构建视频教程(笔记)

热门文章

  1. nvl2可以套公式吗 oracle_oracle nvl2函数
  2. HRB12150-5W小体积高压电源功率密度大直流稳压高压芯片
  3. 2021遥感应用组二等奖:基于时序InSAR上海地区地表沉降时空反演与机理分析
  4. 2021高考成绩估分查询时间,重磅!2021全国各地高考预测分数线出炉,这样估分可以估算全省排名...
  5. Android 图片选择对话框,通过本地相册或照相机获得图片,可单选或多选,单选可设置是否裁剪
  6. M1 MacBook安装soundflower失败情况下如何录屏录制系统内置声音?
  7. dotnet OpenXML 测量单位的角度和弧度值
  8. ASUS华硕ROG幻14 2021款GA401QM原厂Win10系统工厂模式带ASUS Recovery恢复功能
  9. Educoder计算机数据表示实验(HUST)第3关:偶校验编码设计
  10. Bison教你3分钟集成支付宝好友分享