无法将 Class 拆分成更小的

Can't Split Class into Smaller Ones

我无法将 class 拆分成更小的部分。我们有一个 Dto 拥有 30 个不同的 Dto 的糟糕情况。现在我们需要这个 selectDto 的映射,这也迫使我们制作 30 个不同的映射 class。 (我们在项目中也使用了mapstruct,这个场景是mapstruct无法处理的)

现在我的问题开始了:

我在相应的 class 中做了所有映射。在基础 selectDto 中,我的构造函数中有 26 个映射器,这太可怕了:

SonarLint:构造函数有26个参数,大于7个授权

我想出了如何拆分这种场景的方法,但我找不到方法。有什么建议吗?

我的构造函数持有 26 个参数:

    AssignedSelectMapper(AssignedOpDtoMapper assignedOpDtoMapper,
        AssignedOrderDtoMapper assignedOrderDtoMapper
// many more constructor parameters
) {
        this.assignedOptionCodeDtoMapper = assignedOptionCodeDtoMapper;
        this.assignedOrderCriteriaDtoMapper = assignedOrderCriteriaDtoMapper;
        // all settings
}

我的 public 映射函数,它为每个映射调用私有函数:

    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;
}

// 我的私有函数示例,它调用相应的映射器,其中我所有的私有函数都由不同类型的 class 组成,例如 OptionCodeDto。它们不会从同一个 interface/class 延伸,也不能。

 private List<AssignedSelectionCriteria> mapOps(List<OptionCodeDto> optionCodeDtos) {
        return this.assignedOpDtoMapper.mapCriterias(opDtos);
    }

// 这里是反向映射。我需要不同于我的映射 return 类型

的 class
// this is my public function for mapping.
public void assignSelectionTo(SelectionDto selectionDto,
    List<AssignedSelectionCriteria> assignedSelectionCriterias) {

    setOptionCodes(selectionDto, copyCriterias);
    setOrderCriteria(selectionDto, copyCriterias);
    // many more
}

这是反向映射私有函数,每个映射 class returns 不同类型的 dto,如 OptionCodeDto,其中 none 这些 Dto 从相同的 class 扩展.

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);
    }

创建接口AssignedSelectProvider

interface AssignedSelectProvider
{
    List<AssignedSelect> getAssignedSelects();
}

每个mapper实现接口,每个私有方法移到相关class:

class AssignedOpDtoMapper implements AssignedSelectProvider
{
    public List<AssignedSelect> getAssignedSelects()
    {
        return mapOps(getOps());
    }
}

AssignedSelectMapper 在构造函数中获取提供者列表而不是 26 个参数:

class AssignedSelectMapper
{
    AssignedSelectMapper(List<AssignedSelectProvider> mappers)
    {
        //...
    }
}

26 个参数减少到 1 个。

这就像 的扩展。

带有界面的想法是个好主意。虽然在我看来可以更改界面以更适合您的用例:

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 注入您的主 class:

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 个解决方案

1.全部作为 1 个参数传递:

假设您在 1 个构造函数中传递 30 个参数(它们是 DTO),然后创建一个主 DTO 来容纳所有 30 个 DTO,并将该 DTO 作为 ONE 传递参数。

例如:

public class MasterDTO{

private ChildDto1 childDto1 ;
private ChildDto2 childDto2 ;
private ChildDto3 childDto3 ;
...
..
private ChildDto30 childDto30 ;
//public getter setter methds
}

来电者class传递了 30 个 DTOS

public class Caller{
  Functional fun = new Functional(masterDTO);

}

功能性class 期望值为 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();
}

}

2。使用 Setters 方法:

仅传递 7 个元素作为构造函数的参数,然后使用对象并调用 setter 方法来设置剩余的 23 个元素。

来电者class传递了 30 个 DTOS

public class Caller{
  Functional fun = new Functional(childDto1 ,childDto1 , ....childDto7 );
  fun.setChildDto8(childDtoValue8);
  fun.setChildDto9(childDtoValue9);
  fun.setChildDto10(childDtoValue10);
  ...
  ...
  fun.setChildDto30(childDtoValue30);


}