在我的 Spring Boot 应用程序中,我使用 Java Stream API 并将实体值映射到 DTO,如下所示:
public RecipeResponse findById(Long id) {
return recipeRepository.findById(id)
.map(RecipeResponse::new)
.orElseThrow(() -> {
return new NoSuchElementFoundException("Not found");
});
}
但我的回复也有一个列表,我将此列表映射到以下 DTO:
@Data
public class RecipeResponse {
private Long id;
private String title;
private List<RecipeIngredientResponse> ingredients;
public RecipeResponse(Recipe recipe) {
this.id = recipe.getId();
this.title = recipe.getTitle();
this.ingredients = recipe.getRecipeIngredients().stream().map(RecipeIngredientResponse::new).toList();
}
}
我不确定在 DTO 中映射流是一个好主意还是一个合适的主意。我认为将
List<RecipeIngredientResponse>
从服务方法传递给此 DTO 构造函数而不是如上所示将其映射到 DTO 中可能是更合适的方法。这种情况下最合适的方法是什么?
为了遵循SOLID原则,有一些清晰的职责分离,使代码解耦和更容易测试,推荐的做法是将转换逻辑提取到Converter中。
public interface Converter<IN, OUT> {
OUT convert(IN input);
}
将 Recipe 转换为 RecipeResponse 的示例实现:
public class RecipeResponseConverter implements Converter<Recipe, RecipeResponse> {
private final Converter<RecipeIngredient, RecipeIngredientResponse> ingredientConverter;
public RecipeResponseConverter(
Converter<RecipeIngredient, RecipeIngredientResponse> ingredientConverter
) {
this.ingredientConverter = ingredientConverter;
}
@Override
public RecipeResponse convert(Recipe input) {
var response = new RecipeResponse();
response.setId(input.getId());
response.setTitle(input.getTitle());
response.setIngredients(input
.getRecipeIngredients()
.stream()
.map(ingredientConverter::convert)
.toList()
);
return response;
}
}
依赖注入可用于将配方转换器注入服务类,并将配料转换器注入配方转换器,而无需耦合实现。
请注意,使用这种方法,在不知道应该如何转换成分的细节的情况下测试转换配方的各种情况是多么容易,因为可以模拟该成分转换器。