gpt4 book ai didi

java - 使用泛型在 Java 中实现工厂模式

转载 作者:行者123 更新时间:2023-12-05 04:38:09 28 4
gpt4 key购买 nike

我需要 Java 泛型方面的帮助。我的模型是:我有一些扩展 Dto(数据传输对象)的类和一些扩展实体(我的对象模型到 DB)的类。我有

interface Mapper<D extends Dto, E extends Entity>{
//Convert a Entity to Dto.
D toDto(E entity);

我有一些实现此接口(interface)的类(即 PersonMapper、BookMapper 等等)。

@Component    
public class PersonMapper implements Mapper<PersonDto, PersonEntity> {
//implementation
}

@Component
public class BookMapper implements Mapper<BookDto, BookEntity> {
//implementation
}

我想做的是使用工厂模式以便在运行时选择我的映射器,这取决于我传入输入的字符串。

@Autowired
private PersonMapper personMapper;
@Autowired
private BookMapper bookMapper;

public <D extends Dto, E extends Entity> Mapper<D, E> selectMapper(String entity){
if ("Person".equalsIgnoreCase(entity))
return personMapper;
if("Book".equalsIgnoreCase(entity))
return bookMapper;
...
}

在这种情况下,我有以下编译错误:

Type mismatch: cannot convert from PersonMapper to Mapper<D,E>

我的解决方案:

1)

return (Mapper<D, E>) personMapper;

但我有一个警告:

Type Safety: `Unchecked class from personMapper to Mapper<D,H>`

2)

使用 WildCard 和 castingb

public Mapper<Dto, Entity> selectMapper(String entity){
Mapper<? extends Dto, ? extends Entity> toReturn = null;
if ("Person".equalsIgnoreCase(entity))
toReturn = personMapper;
else if("Book".equalsIgnoreCase(entity))
toReturn = bookMapper;
...
return (Mapper<Dto, Entity>) toReturn;
}

但在这种情况下我还有一次警告:

Type safety: Unchecked cast from Mapper<capture#29-of ? extends Dto,capture#30-of ? extends Entity> to Mapper<Dto,Entity>

它有效,但它似乎不是一个干净的解决方案

3) 使用通配符作为返回类型:

public Mapper<? extends Dto, ? extends HistoryEntity> selectMapper(String entity)

但是你知道,根本不推荐使用通配符作为返回类型,这对我也没有帮助,因为我想使用这个映射器并调用 mapper.toDto 确保返回类型是扩展 Dto 的东西。

============================================ ==========================

我不解释为什么要写这样的类构造器

public Service<D extends Dto, E extends Entity>{  
public Service(Mapper<D,E> mapper){
this.mapper = mapper;
}
}

然后我注入(inject)(例如)bookMapper 它起作用了。

相反,如果 Mapper 是返回类型,我将无法执行此类操作。

============================================ ==========================

我请求你的帮助是:

我如何使用干净的代码原则(避免编译警告、sonarlint 问题等)编写解决方案以实现这种逻辑?

非常感谢,如果您花一点时间帮助我解决我的问题,我将不胜感激。

最佳答案

那些关于调用者而不是你的代码的变量(D 和 E)。 D和E是由调用者决定的,所以绝对没有办法保证PersonDTO。适合。

制作Mapper<? extends DTO, ? extends Entity> (并且没有变量),并且鉴于这些已经是下限,只是 Mapper<?, ?> - 那行得通,你可以写你的 return没有任何强制转换且没有编译器错误或警告的语句。

当然,这意味着调用者有一个几乎无用的类型。

泛型完全基于“编译时/写入时”。 JVM ( java.exe ) 不知道泛型是什么,事实上它们中的大多数都无法在编译过程中存活下来。 泛型的唯一目的是让编译器标记不正确的代码并避免某些类型转换,仅此而已

将该字符串转换为 Mapper 的本质完全是运行时的。

因此,如果 Mapper<?, ?>还不够,你想要的是不可能的。你需要编写编译/写入时可检查的东西,所以当你使用字符串时,这是不可能的。例如,一个方法 getPersonMapper()当然可以返回 Mapper<PersonDTO, PersonEntity> ,没问题。

更笼统地说(嘿),听起来您在这里糟糕地重新发明了各种轮子。查看 JDBI、JOOQ 和 Hibernate 的教程,了解通常如何编写与数据库交互的 Java 代码。

关于java - 使用泛型在 Java 中实现工厂模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70637259/

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