Объект шаблона Spring boot builder для dto

#java #spring #spring-boot #design-patterns #builder-pattern

#java #spring #spring-boot #шаблоны проектирования #builder-pattern

Вопрос:

Я создаю API, который передает данные из другого веб-сервиса. Я ищу хорошую практику для преобразования объектов из веб-службы в мой DTO. Преобразование из объекта в DTO имеет некоторую логику.

Теперь я реализовал это (псевдокод):

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

 @Component
public abstract class RelationDtoBuilder <T extends RelationDtoBuilder <T>> {
protected abstract T getThis();

@Autowired
private PhoneNumberDtoBuilder phoneNumberDtoBuilder ;

protected List<PhoneNumberDto> phoneNumbers= new ArrayList<>();

public T setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
    if (phoneNumbers!= null) {
        phoneNumbers.stream().forEach(phoneNumber -> {
            this.phoneNumbers.add(
                    phoneNumberDtoBuilder 
                            .setNumber(branch.getNumber())
                            .setType(branch.getType())
                            .build()
            );            });
    }
    return getThis();
}

}
  

Конструктор подклассов для PersonDTO

 @Component
public final class PersonDtoBuilder extends RelationDtoBuilder<PersonDtoBuilder> {

@Override
protected PersonDtoBuilder getThis() {
    return this;
}

public PersonDto build() {
    PersonDto personDto = new PersonDto();
    PersonDto.setPhoneNumbers(super.phoneNumbers);
    return PersonDto;
}

}
  

Конструктор подклассов для CompanyDto

 @Component
public final class CompanyDtoBuilder extends RelationDtoBuilder<CompanyDtoBuilder > {

protected List<BranchDto> branches = new ArrayList<>();

@Override
protected CompanyDtoBuilder getThis() {
    return this;
}

public CompanyDtoBuilder setBranches(List<Branch> branches) {
    if (branches != null) {
        branches.stream().forEach(branch -> {
            this.branches.add(
                    branchDtoBuilder
                            .setName(branch.getName())
                            .setType(branch.getType())
                            .setPhoneNumbers(branch.getPhoneNumbers)
                            .build()
            );
        });          
    }
    return getThis();
}


public CompanyDtoBuilder build() {
    CompanyDto companyDto= new CompanyDto ();
    companyDto.setPhoneNumbers(super.phoneNumbers);
    companyDto.setBranches(this.branches);
    return CompanyDto;
}


}
  

BranchDtoBuilder

 @Component
public final class BranchDtoBuilder extends RelationDtoBuilder<PersonDtoBuilder>{

@Autowired
private ValueConverterService valueConverterService;

private String name;
private String type;

@Override
protected BranchDtoBuilder getThis() {
    return this;
}

public BranchDtoBuilder setName(String name) {
    this.name= name;
    return this;
}

public BranchDtoBuilder setType(String type) {
    if (type != null) {
        this.type= valueConverterService.convertValue("branchType", type);
    }
    return this;
}

public BranchDtoBuilder build() {
    BranchDto branchDto = new branchDto();
    branchDto.setSoort(this.soort);
    branchDto.setWaarde(this.waarde);
    branchDto.setPhoneNumbers(this.datumIngang);
    return branchDto ;
}

}
  

Проблема в том, что де BranchDtoBuilder использует ту же ссылку для телефонных номеров, что и CompanyDtoBuilder. Как я могу добиться построения DTO без дублирования кода?

Во-вторых, это лучший способ сопоставить объекты с объектами DTO с логикой в виде преобразований базы данных (BranchDtoBuilder)?

Комментарии:

1. is this the best way to map entity to dto's with logic as database conversions — ИМО, вам не нужно усложнять преобразование типов таким образом. Кроме того, best way IMO должен использовать такие инструменты, как интерфейсы mapstruct mapper