gpt4 book ai didi

java - 使用泛型实现对象转换器设计模式

转载 作者:搜寻专家 更新时间:2023-11-01 03:45:43 24 4
gpt4 key购买 nike

我正在尝试为我的 dto <-> 实体类创建一个通用对象转换器。我已经创建了一个抽象类,其中包含两个表示这两种转换的函数,然后在我的具体转换器类中对其进行了扩展。

但我想要一个通用的转换服务,我可以在启动期间注册我的所有转换器,然后方便地调用一个方法来处理彼此之间的转换。

这就是我到目前为止的想法:

转换器抽象类

public abstract class Converter<D, E> {

private final Function<D, E> fromFirstToSecond;
private final Function<E, D> fromSecondToFirst;

public Converter(final Function<D, E> fromFirstToSecond, final Function<E, D> fromSecondToFirst) {
this.fromFirstToSecond = fromFirstToSecond;
this.fromSecondToFirst = fromSecondToFirst;
}

public final E convertFromFirstToSecond(final D first) {
return fromFirstToSecond.apply(first);
}

public final D convertFromSecondToFirst(final E second) {
return fromSecondToFirst.apply(second);
}

}

转换器具体类

public class MyConverter extends Converter<MyDTO, MyEntity> {

public OrderConverter() {
super(
MyConverter::fromDTOToEntity,
MyConverter::fromEntityToDTO
);
}

private static MyEntity fromDTOToEntity(MyDTO dto) {
return MyEntity.builder()
.field1(dto.getField1())
.field2(dto.getField2())
.build();
}

private static MyDTO fromEntityToDTO(MyEntity entity) {
return MyDTO.builder()
.field1(entity.getField1())
.field2(entity.getField2())
.build();
}

}

我想实现这样的目标(这是我需要帮助的地方):

@Configuration
public class ConverterConfiguration {

@Bean
public ConverterService converterService() {
ConverterService converterService = new ConverterService();
converterService.registerConverter(new MyConverter());
// Register any other converter...
return converterService;
}

}

服务看起来像这样:

public class ConverterService {

private Map<Key, Converter<?, ?>> converters = new ConcurrentReferenceHashMap<>();

public void registerConverter(Converter<?, ?> converter) {
this.converterCache.put(key, converter);
}

protected <I, O> I mapBetweenTypes(final O from, final Class<I> clazz) {
// Based on the parameters I should be able to figure out which function to get from the map and then call (convertFromFirstToSecond or convertFromSecondToFirst)
// return this.converters.get(key).convertFromFirstToSecond(from);
return this.converters.get(key).convertFromSecondToFirst(from);
}

}

最佳答案

解决该问题的一种方法是将属于转换一部分的类型显式存储在 Converter 类中。我会考虑的另一个简化是将转换函数直接存储在映射中,而不是转换器。这样您就不必弄清楚您需要走哪条路。

第一步,存储类型,并为转换函数添加 getter:

public abstract class Converter<D, E> {

private final Function<D, E> fromFirstToSecond;
private final Function<E, D> fromSecondToFirst;
private final Class<D> classOfFirst;
private final Class<E> classOfSecond;

public Class<D> getClassOfFirst() {
return classOfFirst;
}

public Class<E> getClassOfSecond() {
return classOfSecond;
}

public Converter(Class<D> first, Class<E> second,
Function<D, E> fromFirstToSecond, Function<E, D> fromSecondToFirst) {
this.fromFirstToSecond = fromFirstToSecond;
this.fromSecondToFirst = fromSecondToFirst;
classOfFirst = first;
classOfSecond = second;
}

public Function<D, E> getForward() {
return fromFirstToSecond;
}

public Function<E, D> getBackward() {
return fromSecondToFirst;
}

然后ConverterService可以存储双向的转换函数,转换相当于一个二级映射中的查找。

public class ConverterService {

private Map<Class<?>, Map<Class<?>, Function<?,?>>> converters = createMap();

public void registerConverter(Converter<?, ?> converter) {
if( !converters.containsKey(converter.getClassOfFirst())) {
converters.put(converter.getClassOfFirst(), createInnerMap());
}
if( !converters.containsKey(converter.getClassOfSecond())) {
converters.put(converter.getClassOfSecond(), createInnerMap());
}
converters.get(converter.getClassOfFirst()).put(
converter.getClassOfSecond(), converter.getForward());
converters.get(converter.getClassOfSecond()).put(
converter.getClassOfFirst(), converter.getBackward());
}

@SuppressWarnings("unchecked") // Also needs input validation
protected <D,E> E mapBetweenTypes(D from, E to) {
return ((Function<D,E>) converters.get(
from.getClass()).get(to.getClass())).apply(from);
}

private static Map<Class<?>, Map<Class<?>, Function<?,?>>> createMap() {
return /* Whatever impl you need */
}

private static Map<Class<?>, Function<?,?>> createInnerMap() {
return /* Whatever impl you need */
}
}

关于java - 使用泛型实现对象转换器设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57665221/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com