Существует ли какая-либо структура сопоставления классов, которая работает со строителями? Я хотел бы сохранить некоторые из моих классов неизменными и избежать множественных конструкторов — на помощь приходит шаблон Builder. Однако я не могу использовать структуру сопоставления, которая автоматически использовала бы билдер вместо геттеров/сеттеров.
Платформа сопоставления объектов Java, работающая с шаблоном построителя
Ответы (2)
Это можно легко сделать с помощью MapStruct и специальной стратегии именования для строителей.
Посмотрите здесь в документации, как использовать стратегию именования Custom Accessor.
Тогда ваши сопоставления должны выглядеть так:
@Mapper
public interface MyMapper {
default Immutable map(Source source) {
return mapToBuilder(source).build();
}
Immutable.Builder mapToBuilder(Source source);
}
В MapStruct мы уже работаем над функцией, которая будет поддерживать встроенную поддержку сборщиков. Вы можете следить за этой проблемой для получения более подробной информации.
Обновлять
MapStruct теперь (начиная с версии 1.3.0.Beta1) имеет встроенную поддержку Immutables. Это означает, что прежний преобразователь может быть написан так:
@Mapper
public interface MyMapper {
Immutable map(Source source);
}
Предполагается, что существует общедоступный статический метод без параметров в Immutable
, который возвращает сборщик
Я получил следующее, работая с Lombok
и ModelMapper
. См.: http://modelmapper.org/getting-started/
public class MyService {
private ModelMapper modelMapper;
public MyService(){
this.modelMapper = new ModelMapper();
this.modelMapper.getConfiguration()
.setMatchingStrategy(MatchingStrategies.STRICT)
.setDestinationNamingConvention(LombokBuilderNamingConvention.INSTANCE)
.setDestinationNameTransformer(LombokBuilderNameTransformer.INSTANCE);
}
public OutputDTO aMethod(final InputDTO input){
return modelMapper.map(input, OutputDTO.OutputDTOBuilder.class).build();
}
}
Где LombokBuilderNamingConvention
:
import org.modelmapper.spi.NamingConvention;
import org.modelmapper.spi.PropertyType;
public class LombokBuilderNamingConvention implements NamingConvention {
public static LombokBuilderNamingConvention INSTANCE = new LombokBuilderNamingConvention();
@Override
public boolean applies(String propertyName, PropertyType propertyType) {
return PropertyType.METHOD.equals(propertyType);
}
@Override
public String toString() {
return "Lombok @Builder Naming Convention";
}
}
И LombokBuilderNameTransformer
это:
import org.modelmapper.spi.NameTransformer;
import org.modelmapper.spi.NameableType;
public class LombokBuilderNameTransformer implements NameTransformer {
public static final NameTransformer INSTANCE = new LombokBuilderNameTransformer();
@Override
public String transform(final String name, final NameableType nameableType) {
return Strings.decapitalize(name);
}
@Override
public String toString() {
return "Lombok @Builder Mutator";
}
}
И OutputDTO
может выглядеть так:
@Builder // Has .builder() static method
@Value // Thus immutable
public class OutputDTO {
private String foo;
private int bar;
}