프로젝트 요구사항 중, DTO 하나를 상속해서 필드를 추가할 필요가 있었다. 기존 GetSolutionResponse
DTO에서 그룹 아이디를 추가해 넘겨줘야 했는데, 그룹 Id가 없는 기존의 GetSolutionResponse
도 다른 API에서 필요했다. 그래서 GetSolutionResponse
와 동일한 DTO를 하나 더 파서 거기에 groupId를 추가해야 하는데, 그러기엔 기존 DTO가 필드도 많고 헤비해 이런 클래스를 또 만들어야 하는 건 너무 재사용성이 떨어지는 설계라고 생각했다.
그래서 생각한 방법이 GetSolutionResponse
를 상속하는 것이었는데, 이 때 @Builder
를 사용하니 문제가 발생했다.
@Builder
는 상속받은 필드를 builder에 사용할 수 없다. 즉, 자식 클래스에서는 새로 생성한 필드만 builder에 추가할 수 있다는 것이다. 나는 상속받은 모든 필드도 builder 패턴에 추가돼야 했기에, 다른 방법을 모색했다.
@SuperBuilder
는 생성자에서 상속 받은 필드도 builder에 사용 가능하다.
이 어노테이션은 부모, 자식 클래스 모두 어노테이션을 추가해야 한다.
기존의 부모 DTO는 아래와 같다.
@Builder
@Getter
public class GetSolutionResponse {
private Long solutionId;
...
private Long commentCount;
public static GetSolutionResponse toDTO(Solution solution, Long commentCount) {
return GetSolutionResponse.builder()
.solutionId(solution.getId())
...
.commentCount(commentCount)
.build();
}
}
여기서 @Builder
를 제거하고 @SuperBuilder
로 바꿔줘야 한다.
@SuperBuilder
@Getter
public class GetSolutionResponse {
private Long solutionId;
...
private Long commentCount;
public static GetSolutionResponse toDTO(Solution solution, Long commentCount) {
return GetSolutionResponse.builder()
.solutionId(solution.getId())
...
.commentCount(commentCount)
.build();
}
}
@SuperBuilder
는 자식 클래스에도 달아주어야 한다.
@SuperBuilder
@Getter
public class GetSolutionWithGroupIdResponse extends GetSolutionResponse {
private final Long groupId;
public static GetSolutionWithGroupIdResponse toDTO(Solution solution, Long commentCount) {
return GetSolutionWithGroupIdResponse.builder()
.solutionId(solution.getId())
...
.commentCount(commentCount)
.groupId(solution.getProblem().getStudyGroup().getId())
.build();
}
}
이제 부모 필드를 자식 DTO builder에서도 사용할 수 있게 되었다.