사내에서 인스턴스 생성을 어떻게 할 건지에 대해 얘기하다가 이전 회사에서 빌더를 이용한 것 보다 static factory method로 만들자고 했었던 거 때문에 생성자를 이용하거나 of 메서드를 이용한 것이 좋다고 주장했었는데 분명한 근거를 대지 못하던 차에 Effective Java 1장부터 그 내용이 나왔고 이해한 내용을 바탕으로 책을 정리해보기로 하였다.
public static factory 메서드를 이용해서 인스턴스를 생성해서 반환하는 것이다.
생성자 자체는 인스턴스의 속성을 분명하게 알기 애매한 부분이 있다.
class Family {
String mother;
String father;
String daughter;
String son;
public Family(String mother, String father, String daughter, String son) {
this.mother = mother;
this.father = father;
this.daughter = daughter;
this.son = son;
}
}
위와 같이 생성자가 있을 때, (mother, father) 만 있다던지, daughter나 son를 추가하여 있는 경우 생성자의 경우 똑같은 타입을 파라미터로 받는 생성자를 두 개이상 만들 수 없기에 애매한 부분이 있다.
아래와 같이 static factory method를 이용해서 만들면 어떤 목적으로 인스턴스를 생성하는지 명시적으로 알 수 있다.
public static Family create(String mother, String father) {
Family family = new Family();
this.mother = mother;
this.father = father;
return family;
}
public static Family createWithDaughter(String mother, String father, String daughter) {
Family family = new Family();
this.mother = mother;
this.father = father;
this.daughter = daughter;
return family;
}
}
여러 번 호출되더라도 이미 생성된 동일 객체를 반환하기 때문에, 인스턴스의 존재를 직접 제어할 수 있다. 이러한 일을 하는 클래스를 인스턴스 제어 클래스라고 하는데, 인스턴스 제어 클래스는 싱글톤/ 인스턴스 생성불가 클래스로 만들 수 있고 관련된 내용은 3, 4장에서 학습 예정이다. 또한 불변클래스에서 동일 여부를 equals 가 아닌 == 으로도 가능해서 프로그램 성능도 향상될 수 있다고 하는데, equals로 하면 하나하나 비교고 == 주소값만으로도 비교되서 그런건가 싶다. 이 부분도 15장에서 알 수있다고 한다.
public interface List {
}
public class ArrayList implements List{
public static List asList(int a)
return new ArrayList(a);
}
위의 코드는 저런 경우가 생각이 안나서 만들어본건데, 대표적으로 java.util.Collection에서 static factory method를 이용해서 45개의 유틸리티 구현체를 제공한다.
Chlid/ Adult가 Person을 상속받고 있다면 입력 변수에 따라 객체의 형태를 다양하게 반환받을 수 있다.
class Person {
String name;
public static Person newInstance(String name, int age) {
if(age < 20 ) return new Child();
return new Adult();
}
}
그치만 이 부분은 상속 대신 컴포지션을 사용하도록 유도할 수 있기에 장점이 될 수도 있다.
이게 인스턴스 생성하는 static인지 아닌지 구별이 어렵다는 의미로 이해된다. 생성자의 경우 Javadoc에서 자동으로 상단에 모아서 보여준다.
단점 2를 보완하기 위해 메소드 명을 잘 지어야하는데 예시는 아래와 같다.
effective java