본문 바로가기

롱런 프로젝트

빌더 패턴에 생성자 파라미터를 강제하거나 강제하지 않을 때

 

빌더 패턴을 사용하면 private 생성자에

중첩 클래스인 Builder 클래스을 통하여 해당 필드값을 채워 넣는다.

 

빌더 패턴은 클래스의 필드값이 여러개인데 (좀 많을 때)

해당 필드값들이 모두 필요하지 않을 때 자주 사용된다.

 

 

Effective Java 3/E - item2

 

"점층적 생성자 패턴도 쓸 수는 있지만, 매개변수 개수가 많아지면 클라이언트 코드를 작성하거나 읽기 어렵다."

 

현 프로젝트에서는 Study 객체의 정보를 담당하기 위한

StudyCondition 클래스를 정의하는데 이 정보들이 모두 필요하지 않았다.

게다가 이 객체를 활용하여 Study 객체를 비교하거나 필터링 하는데도

유용하게 사용할 수 있을 거라 생각했다.

 

그래서 StudyCondition 객체를 Builder 패턴으로 정의했다.

그리고 문제점이 생겼다.

 

내가 만들 Study 객체의 StudyInformation 에는 필수적으로 들어가야할 필드들이 있는데

( 스터디의 시작 날짜, 끝 날짜, 요일과 시각, 장소 를 필수 필드라고 생각했다 )

비교하거나 필터링할때 사용하는 StudyInformation 은 필수항목이 아닐뿐더러

( 필터링 할때는 시작날짜 또는 끝날짜 또는 ~~  으로도 가능하기 때문 )

필요하지 않은 데이터는 제거해야 했기 때문이다.

 

그래서

 

1. StudyCondition 의 Builder 에 필수 파라미터를 제거하고,

StudyCondition을 확장한 StudyInformation 클래스를 정의하여

StudyInformation 생성자에 강제 파라미터를 적용하려고 했다.

 

StudyCondition 은 private 생성자로 인해 확장이 불가능했다.

 

2. StudyCondition 을 필드로 갖는 형태로 StudyInformation 클래스를 정의했다.

이 때 문제점은 StudyCondtion 을 리턴하려면 build() 메서드를 실행해야 했고,

 

그 때문에 더 추가하고 싶은 필드들은 추가할 수가 없었다.

 

3.  StudyCondition 의 Builder 를 확장하는 StudyInformation 클래스를 정의했다.

Builder 안의 데이터가 확장되며 필드를 추가할 수 있는 체이닝 메서드까지도 사용할 수 있었다.

그러나 체이닝 메서드를 사용하면 결국 반환되는 값이 StudyCondition.Builder 객체가 되므로

Study 생성자에 파라미터를 StudyCondition.Builder 로 넓혀야 했다.

이러면 해당 Study 객체를 생성하는 클라이언트( 개발자 )는 해당 사실을 모른채

StudyInformation 이 아닌 StudyCondition.Builder 객체를 사용하게 될 수도 있다.

 

그렇게 되면 결국 필수 파라미터를 강제 할 수 없게 된다.

 

...

 

결국 강제성 띄는 코드를 짜기위해 이런 저런 짓을 해봤지만

 

Study 내에서 validate 메서드를 작성하여 해당 필드들을 검사하는 게 더 편하고 좋을 거 같다고 생각했다.