构建型设计模式-Converter

模式意图

提供一种通用的方法来实现两种数据类型之间的相互转换,从而最大化地减少样板代码的编写。

现实案例

在日常Java开发过程中,我们经常需要根据各种需求做类型转换,如:

  • 为执行业务处理,经常需要将VO转换成DTO
  • 为存储业务数据,经常需要将DTO转换为PO
  • 为展示相关数据,经常需要将PO转换为VO
  • 为调用服务提供方接口,经常需要将自己的对象转换成服务提供方提供的请求对象

解决方案

为解决不同类型之间的转换问题,我们提供如下两个类:

  • BDConverter:泛型双向转换器,用于处理两种类型之间需要相互转换的场景。
  • UDConverter:泛型单向转换器,用于处理单向转换场景。

类图如下:


构建型设计模式-Converter

BDConverter类:

<code>import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description: 泛型双向转换器
* @author hxj
* @date 2020年4月2日
* @param  源类型
* @param  目标类型
*/
public class BDConverter {
private final Function forwardFunction;
private final Function reverseFunction;
/**
 ** 构造器
 *  @param forwardFunction 将S转换为T的正向函数
 * @param reverseFunction 将T转换为S的逆向函数
 */
public BDConverter(final Function forwardFunction, final Function reverseFunction) {
 this.forwardFunction = forwardFunction;
 this.reverseFunction = reverseFunction;
}
 
/** 将S对象正向转换为T对象
 * @param  s  源对象
 * @return T  目标对象
 */
public final T forwardConvertWithOne(final S s) {
 return forwardFunction.apply(s);
}

/**
 **将T对象逆向转换为S对象
 * @param  t  目标对象
 * @return S    源对象
 */
public final S reverseConvertWithOne(final T t) {
 return reverseFunction.apply(t);
}

public final List forwardConvertWithList(final Collection ss) {
 return ss.stream().map(this::forwardConvertWithOne).collect(Collectors.toList());
}

public final List reverseConvertWithList(final Collection tt) {
 return tt.stream().map(this::reverseConvertWithOne).collect(Collectors.toList());
}
}
/<code>

UDConverter类:

<code>import java.util.Collection;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* @Description: 泛型单向转换器
* @author hxj
* @date 2020年4月2日
* @param  原始类型
* @param  目标类型

*/
public class UDConverter {
private final Function convertFunction;
public UDConverter(Function convertFunction) {
 this.convertFunction = convertFunction;
}
public final T convertFromOne(final S s) {
 return convertFunction.apply(s);
}
 
/**
 **将原始集合转换为目标列表
 * @param  ss  原始集合

 * @return  目标列表
 */
public final List convertFromCollection(final Collection ss) {
 return ss.stream().map(this::convertFromOne).collect(Collectors.toList());
}
}
/<code>

模式优势

  • 将类型转换逻辑从业务代码中剥离,使类的职责更清晰(单一职责原则)。
  • 复用类型转换逻辑,同时也方便在一个地方控制类型之间的转换逻辑。



编程示例

下面我们编写一个StringSerializer来实现字符串的序列化与反序列化功能,类图如下:


构建型设计模式-Converter


下面是转换器实现:

<code>import com.ywkj.base.converter.BDConverter;
public class StringSerializer extends BDConverter<string> {
public StringSerializer() {
     super(StringSerializer::toByte, StringSerializer::toString);
}
private static byte[] toByte(String s) {
     return s.getBytes();
}

private static String toString(byte[] s) {
     return new String(s);
}
}/<string>/<code>

使用代码:

<code>public static void main(String[] args) {
 StringSerializer converter = new StringSerializer();
 String str="abcde";
 //正向转换,将String转换成byte[]
 byte[] byteArr = converter.forwardConvertWithOne(str);
//反向转换,将byte[]转换成String
 String result = converter.reverseConvertWithOne(byteArr);
 System.err.println(str.equals(result));
 
//集合形式的类型转换
 List<byte> list = converter.forwardConvertWithList(Lists.newArrayList("a","b"));
 List<string> resultList= converter.reverseConvertWithList(list);
 System.err.println(resultList);
}/<string>/<byte>/<code>

其它资料

spring framework内部也大量使用了Converter设计模式,下面是Converter实现类不完整截图:


构建型设计模式-Converter


通过上面的截图,很容易看出转换器的实际功能,调用时一目了然。


分享到:


相關文章: