사진은 그냥 플레이스토어에서 가져왔다...ㅎ
현재 프로젝트는 위와 같이 사용자가 헤어에디터를 사용하면 Spring 서버에 API가 전송되고 Spring 서버는 헤어 Editing을 담당하는 AI서버에 실제 헤어합성 요청을 보내는 형태로 구현되어있다.
위의 예시처럼 앞머리 에디터, 남자헤어 에디터, 대머리 ~~ 등 각 헤어에디터 기능마다 생성에 필요한 값들이 모두 다르기에 각기 다른 Request 객체로 관리했다. 하지만 요청에 필요한 파라미터가 증가하면서 요청마다 필요한 고유한 값들이 찾기 어려워지고 가독성이 저하되는 문제가 발생했다.
때문에 기능마다 Request 객체를 만들던 방식에서 SuperBuilder를 활용하여 공통 요소를 가진 상위 객체를 만들고, 이를 상속받아 각각의 하위 객체들을 정리하는 방식을 도입하여 코드를 정리해보려 한다.
SuperBuilder는 Lombok 라이브러리에서 제공하는 기능 중 하나로, 빌더 패턴을 효율적으로 사용할 수 있도록 도와주는 어노테이션이다. 상위 클래스에 사용하면 하위 클래스에서 간편하게 빌더 패턴을 활용할 수 있어 코드의 가독성과 유지보수성을 향상시킬 수 있다.
상위 객체의 필드를 하위 객체에서 재사용하고자 한다면, super 키워드를 통해 하위 클래스에서 상위 클래스의 필드를 중복 정의하지 않고 사용할 수 있다.
하지만 현재 request 객체에 존재하는 필드는 20개이상의 공통필드와 고유한 필드가 같이 존재했다. 이 공통필드에 값은 모든 요청마다 상이한데 super 키워드를 사용할시 각 매개변수가 어떤 필드의 값을 의미하는지 알 수 없었다. 때문에 필자는 직관적으로 각 값이 어떤 필드에 해당하는지 비교할 수 있는 SuperBuilder를 사용해 가독성을 높이고 코드를 정리했다.
super 키워드는 표준 자바 문법을 따르며 명시적인 사용이 가능하나, 코드의 길이가 길어지고 가독성이 저하될 수 있다.... 반면, @SuperBuilder는 롬복 라이브러리를 활용하여 더 간결한 코드를 작성할 수 있지만, 라이브러리 의존성이 추가되므로 프로젝트의 상황에 맞게 선택하는 것이 좋을 것 같다..! 😊
@Getter
@NoArgsConstructor
public class EditorBangRequests {
private String specificField1
private String specificField2
private String sd_model_checkpoint;
private String prompt;
private String negative_prompt;
private String prompt1;
private String prompt2;
private String prompt3;
private String prompt4;
private String prompt5;
...
...
// 20개 이상의 필드
public static EditToolBangRequests create(){
EditorBangRequests req = new EditorBangRequests();
req.sd_model_checkpoint = "....."
.
.
//20개 이상의 필드
}
}
@Getter
@NoArgsConstructor
public class EditorFullHairRequests{
private String specificField3
private String sd_model_checkpoint;
private String prompt;
private String negative_prompt;
private String prompt1;
private String prompt2;
private String prompt3;
private String prompt4;
private String prompt5;
...
...
// 20개 이상의 필드
public static EditorFullHairRequests create(){
EditorFullHairRequests req = new EditorFullHairRequests();
req.sd_model_checkpoint = "....."
.
.
//20개 이상의 필드
}
}
@Getter
@NoArgsConstructor
public class EditorBaldRequests{
private String sd_model_checkpoint;
private String prompt;
private String negative_prompt;
private String prompt1;
private String prompt2;
private String prompt3;
private String prompt4;
private String prompt5;
...
...
// 20개 이상의 필드
public static EditorBaldRequests create(){
EditorBaldRequests req = new EditorBaldRequests();
req.sd_model_checkpoint = "....."
.
.
//20개 이상의 필드
}
}
.
.
.
// 상위 객체 선언
// 직접 인스턴스화하지 않을 것이기 때문에 추상 클래스로 생성한다.
@Getter
@SuperBuilder
public abstract class BaseEditorRequest {
private String sd_model_checkpoint;
private String prompt;
private String prompt1;
private String prompt2;
private String prompt3;
private String prompt4;
private String prompt5;
.
.
// 공통필드
}
@Getter
@SuperBuilder
public class EditorBaldRequests extends BaseEditToolRequest {
private String specificField1
private String specificField2
public static EditorBaldRequests create(String imgName, ...) {
...
return EditToolBaldRequest.builder()
.sd_model_checkpoint("~~~~")
...
.build();
}
}
@Getter
@SuperBuilder
public class EditorFullHairRequests extends BaseEditToolRequest {
private String specificField3
public static EditorFullHairRequests create(String imgName, ...) {
...
return EditorFullHairRequests.builder()
.sd_model_checkpoint("~~~~")
...
.build();
}
}
@Getter
@SuperBuilder
public class EditorBaldRequests extends BaseEditToolRequest {
public static EditorBaldRequests create(String imgName, ...) {
...
return EditorBaldRequests.builder()
.sd_model_checkpoint("~~~~")
...
.build();
}
}