Платформа сопоставления объектов Java, работающая с шаблоном построителя

Существует ли какая-либо структура сопоставления классов, которая работает со строителями? Я хотел бы сохранить некоторые из моих классов неизменными и избежать множественных конструкторов — на помощь приходит шаблон Builder. Однако я не могу использовать структуру сопоставления, которая автоматически использовала бы билдер вместо геттеров/сеттеров.


person r3nw0rp    schedule 02.10.2017    source источник
comment
Я не уверен в ваших точных требованиях, но Project Lombok, возможно, стоит посмотреть...   -  person JensS    schedule 02.10.2017


Ответы (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, который возвращает сборщик

person Filip    schedule 02.10.2017

Я получил следующее, работая с 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;
} 
person ther    schedule 25.03.2018