5
votes

Impossible de diviser la classe en plus petits

J'ai du mal à diviser ma classe en plusieurs parties. Nous avons une mauvaise situation où un Dto détient 30 Dtos différents. Nous avons maintenant besoin de ce mappage de selectDto qui nous oblige également à créer 30 classes de mappage différentes. (Nous utilisons également mapstruct dans le projet, ce scénario est différent de ce que mapstruct peut gérer)

Maintenant où mon problème commence:

J'ai fait tous les mappages dans la classe correspondante. Dans le selectDto de base, j'ai 26 mappeurs dans mon constructeur ce qui est horrible:

SonarLint: Constructor a 26 paramètres, ce qui est supérieur à 7 autorisés

Je réfléchis à la façon de diviser ce genre de scénario mais je n'ai pas trouvé de moyen. Des suggestions?

Mon constructeur contenant 26 paramètres:

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

ma fonction publique à mapper qui appelle des fonctions privées pour chaque mappage:

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

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

// exemple de ma fonction privée qui appelle le mappeur correspondant où toute ma fonction privée consiste en différents types de classe comme OptionCodeDto ici. Ils ne s'étendent pas à partir de la même interface / classe et ne peuvent pas.

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

// et voici le mappage inversé. Dont j'ai besoin d'un type de classe différent de mon type de retour de mappages

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

et c'est la fonction privée de mappage inversé que chaque classe de mappage renvoie différents types de dto comme OptionCodeDto où aucun de ceux-ci Les Dto s'étendent de la même classe.

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


5 commentaires

Peut-être que cela peut aider: softwareengineering.stackexchange.com/questions/311297/...


Toutes les fonctions privées reçoivent-elles List optionCodeDto comme paramètre ou le type peut-il varier?


Oui, ils varient tous et ne s'étendent pas et ne peuvent pas provenir de la même interface / classe de base


D'accord. Vous devez le spécifier dans votre question car il importe la solution globale.


Merci, j'ai mis à jour.


3 Réponses :


2
votes

Créez une interface AssignedSelectProvider

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

chaque mappeur implémente l'interface et chaque méthode privée passe à la classe appropriée:

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


0 commentaires

2
votes

Cela agit comme une extension de réponse @Michaels .

L'idée avec une interface est une excellente idée. Bien qu'à mon avis, l'interface puisse être modifiée pour être plus adaptée à votre cas d'utilisation:

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

Maintenant, chaque mappeur implémente cette interface:

private final List<SelectDtoProcessor> processors;

AssignedSelectMapper(List<SelectDtoProcessor> processors) {
    this.processors = processors;
}


0 commentaires

1
votes

Il existe 2 solutions pour cela

1. Passez tout comme 1 argument:

Supposons que vous passiez 30 arguments (qui sont des DTO) dans 1 constructeur, puis créez un DTO maître qui contiendra les 30 DTO et transmettez ce DTO comme argument ONE .

par exemple:

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


}

Classe d'appelant pour passer 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();
}

}

Classe fonctionnelle qui attend une valeur de 30 DTOS

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

}

2. Utilisez les méthodes Setters:

Passez seulement 7 éléments comme argument du constructeur, puis utilisez l'objet et appelez les méthodes setter pour définir les 23 éléments restants.

Classe d'appelant pour passer 30 DTOS

public class MasterDTO{

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


0 commentaires