我在将班级分成更小的部分时遇到麻烦。一个Dto拥有30个不同的Dto的情况很糟糕。现在我们需要这个selectDto的映射,这也迫使我们创建30种不同的映射类。 (我们在项目中也使用了mapstruct,这种情况与mapstruct可以处理的情况不同)
现在我的问题开始了:
我在对应的类中进行了所有映射。在基本的selectDto中,我的构造函数中有26个映射器,这很可怕:
SonarLint:构造函数具有26个参数,大于7个授权参数
我想出了如何分解这种情况的方法,但是我找不到方法。有什么建议吗?
我的构造函数包含26个参数:
AssignedSelectMapper(AssignedOpDtoMapper assignedOpDtoMapper,
AssignedOrderDtoMapper assignedOrderDtoMapper
// many more constructor parameters
) {
this.assignedOptionCodeDtoMapper = assignedOptionCodeDtoMapper;
this.assignedOrderCriteriaDtoMapper = assignedOrderCriteriaDtoMapper;
// all settings
}
我要映射的公共函数,它为每个映射调用私有函数:
public List<AssignedSelect> assignSelectFrom(SelectDto selectDto) {
Objects.requireNonNull(selectionDto, "selectionDto can not be NULL");
List<AssignedSelect> assignedSelects= new ArrayList<>();
assignedSelects.addAll(this.mapOps(selectionDto.getOps()));
assignedSelects.addAll(this.mapOra(selectionDto.getOra()));
assignedSelects.addAll(this.mapOrs(selectionDto.getOrs()));
assignedSelects.addAll(this.mapSs(selectionDto.getSs()));
assignedSelects.addAll(this.mapDels(selectionDto.getDels()));
assignedSelects.addAll(this.mapMs(selectionDto.getMs()));
assignedSelects.addAll(this.mapBrs(selectionDto.getBrs()));
assignedSelects.addAll(this.mapEqs(selectionDto.getEqs()));
assignedSelects.addAll(this.mapPaints(selectionDto.getPaints()));
assignedSelects.addAll(this.mapBas(selectionDto.getBas()));
// more ...
// and more...
return assignedSelects;
}
//我的私有函数的示例,该函数调用相应的映射器,其中我的所有私有函数都包含不同种类的类,例如OptionCodeDto。它们不会从相同的接口/类扩展而来。
private List<AssignedSelectionCriteria> mapOps(List<OptionCodeDto> optionCodeDtos) {
return this.assignedOpDtoMapper.mapCriterias(opDtos);
}
//,这是反向映射。我需要与映射返回类型不同的类
// this is my public function for mapping.
public void assignSelectionTo(SelectionDto selectionDto,
List<AssignedSelectionCriteria> assignedSelectionCriterias) {
setOptionCodes(selectionDto, copyCriterias);
setOrderCriteria(selectionDto, copyCriterias);
// many more
}
这是反向映射私有函数,每个映射类都返回不同类型的dto,例如OptionCodeDto,而这些Dto都不是同一类的扩展。
private void setOptionCodes(SelectionDto selectionDto, List<AssignedSelectionCriteria> assignedSelectionCriterias) {
// this is where I have trouble, each mapping returns different Dto's
List<OptionCodeDto> optionCodeDtos =
this.assignedOptionCodeDtoMapper.mapAssignedCriterias(assignedSelectionCriterias;
selectionDto.setOptionCodes(optionCodeDtos);
}
答案 0 :(得分:2)
创建界面AssignedSelectProvider
interface AssignedSelectProvider
{
List<AssignedSelect> getAssignedSelects();
}
每个映射器都实现该接口,并且每个私有方法都移至相关的类:
class AssignedOpDtoMapper implements AssignedSelectProvider
{
public List<AssignedSelect> getAssignedSelects()
{
return mapOps(getOps());
}
}
AssignedSelectMapper
获取构造函数中的提供程序列表,而不是26个参数:
class AssignedSelectMapper
{
AssignedSelectMapper(List<AssignedSelectProvider> mappers)
{
//...
}
}
这是26个参数,降至1。
答案 1 :(得分:2)
这就像对@Michaels answer的扩展。
带有接口的想法是一个好主意。尽管我认为可以更改界面以更适合您的用例:
interface SelectDtoProcessor {
void process(SelectDto dto,
Consumer<? super Collection<? extends AssignedSelect>> action);
}
现在每个映射器都实现此接口:
class AssignedOpDtoMapper implements SelectDtoProcessor {
@Override
public void process(SelectDto dto,
Consumer<? super Collection<? extends AssignedSelect>> action){
List<OptionCodeDto> ops = dto.getOps();
consumer.accept(mapCriterias(ops));
}
然后将所有这些Processors
注入您的主类:
private final List<SelectDtoProcessor> processors;
AssignedSelectMapper(List<SelectDtoProcessor> processors) {
this.processors = processors;
}
最后遍历您方法中的所有处理器:
public List<AssignedSelect> assignSelectFrom(SelectDto selectDto) {
Objects.requireNonNull(selectionDto, "selectionDto can not be NULL");
List<AssignedSelect> assignedSelects= new ArrayList<>();
for(SelectDtoProcessor processor: processors) {
processor.process(selectDto, assignedSelects::addAll);
}
return assignedSelects;
}
答案 2 :(得分:0)
有2种解决方案
1。全部以1个参数传递:
假设您要在1个构造函数中传递30个参数(即DTO),然后制作一个主DTO来容纳所有30个DTO,然后将该DTO作为 ONE 参数传递。
例如:
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.7.3/Chart.min.js"></script>
<button id="add">Add Series</button> Click a bar to increment its value by 1.
<canvas id="chart"></canvas>
用于传递30个DTOS的呼叫者类
public class MasterDTO{
private ChildDto1 childDto1 ;
private ChildDto2 childDto2 ;
private ChildDto3 childDto3 ;
...
..
private ChildDto30 childDto30 ;
//public getter setter methds
}
功能类,期望值为30 DTOS
public class Caller{
Functional fun = new Functional(masterDTO);
}
2。使用设置器方法:
仅传递7个元素作为构造函数的参数,然后使用object和call setter方法设置其余23个元素。
用于传递30个DTOS的呼叫者类
class Functional{
private ChildDto1 childDto1 ;
private ChildDto2 childDto2 ;
private ChildDto3 childDto3 ;
...
...
public Functional(MasterDTO masterDTO){
childDto1 = masterDTO.getChildDto1();
childDto2 = masterDTO.getChildDto2();
childDto3 = masterDTO.getChildDto3();
...
...
childDto30 = masterDTO.getChildDto30();
}
}