Не могу разделить класс на меньших - PullRequest
0 голосов
/ 09 января 2019

У меня проблема с разделением моего класса на более мелкие части. У нас плохая ситуация, когда Dto содержит 30 различных Dtos. Теперь нам нужно это отображение 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);
    }

Ответы [ 3 ]

0 голосов
/ 09 января 2019

Это действует как расширение @ 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;
}
0 голосов
/ 09 января 2019

Для этого есть 2 решения

1. Передайте все как 1 Аргумент:

Предположим, вы передаете 30 аргументов (которые являются DTO) в 1 конструктор, затем создаете Master DTO, который будет содержать все 30 DTO, и передаете этот DTO как ONE аргумент.

например:

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

}

Функциональный класс, который ожидает значение 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 элементов в качестве аргумента конструктора, затем используйте методы объекта и метода вызова для установки оставшихся 23 элементов.

Класс вызывающего абонента для прохождения 30 DTOS

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


}
0 голосов
/ 09 января 2019

Создать интерфейс 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.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...