자바 객체를 만들 때 내부 생성자
를 만드는 대신 정적 팩토리 메소드
를 통해 객체를 생성하도록 강요하는 것이 좋다.
점증적 생성자 패턴
이다.(결론부터 말하면, 정적 팩토리 메서드안에 객체를 리턴할 때 빌더패턴
으로 사용하면 더 좋다. 개인적으로 빌더패턴으로 객체를 생성하는 방식을 더 선호한다. 이유는 아래 글을 보면 알 수 있을 것이다.)
클래스들은 가변적이여야 하는 매우 타당한 이유가 있지 않는 한 반드시 불변으로 만들어야 한다. 만약 클래스를 불변으로 만드는 것이 불가능하다면, 가능한 변경 가능성을 최소화하라.
By Effective Java
개인적으로 사용하는 방법으로
빌더 패턴(final 사용) + 정적 팩토리 메서드 방식을 애용한다.
빌더 패턴의 유연함이 그나마 new 연산자로 시작하지 않고 파라미터 순서에 구애받지 않다. 그리고 final 키워드는 빌더 패턴의 생성자 내 필드들의 불변을 위한 것이다.
공장이 하는일?
그렇다긴 보다, 복잡한 생산과정을 숨기고, 완성된 인스턴스만 반환하는 것!
위에 내가 말한 방법으로 사용하면 동시성 이슈없이 thread-safe 하다.
일단 Static 정적 팩토리 메서드는 일반적으로 thread-safe할 수 있는 방식은 다음과 같다.
1) Immutable 객체 생성
static 쓰는 이유! static 키워드로 정적 팩토리 메서드를 사용하여 불변 객체를 생성한다. 해당 객체는 한 번 생성되면 변경되지 않기 때문에 thread-safe한 것이다!
2) 로컬 변수만 사용
Static 정적 팩토리 메서드는 인스턴스 변수를 사용하지 않고, 오직 지역 변수만 사용합니다. 이는 메서드 호출이 동기화를 필요로 하지 않기 때문에 thread-safe합니다.
3) 내부 변수 공유 X
Static 정적 팩토리 메서드가 생성한 객체의 내부 상태를 다른 객체와 공유하지 않는 경우, 해당 객체는 thread-safe합니다.
4) 그외
하지만 만약 static 정적 팩토리 메서드가 mutable 객체를 생성하고, 그 객체 내부의 상태를 다른 객체와 공유하는 경우, thread-safe하지 않게 된다.
이 경우에는 synchronized
를 사용하여 동기화를 수행하거나, ThreadLocal
을 사용하여 각 스레드에 대해 별도의 인스턴스를 생성하는 것이 좋다.
출처: https://mangkyu.tistory.com/131 [MangKyu's Diary]