-
생성자 대신 static 팩토리 메소드 고려해보기JAVA/Effective java 2020. 2. 27. 16:15
- 클래스는 생성자와 별도로 정적 팩토리 메서드(static factory method)를 제공할 수 있다.
- 그 클래스의 인스턴스를 반환하는 단순한 정적 메서드 말이다.
- 클래스는 public 생성자 대신 정적 팩토리 메서드를 제공할 수 있다.
- 이 방식은 장단점이 존재한다.
장점
1. 이름을 가질 수 있다.
- 다음과 같이 생성자는 그 클래스와 동일한 이름으로만 만들어야 하지만
- 거기서 반환하는 객체를 잘 설명하지 못할 경우, 잘 만든 이름을 가진 static 팩토리를 사용하는 것이 보다 쉽고 읽기 편하다는 것.
- 또 똑같은 타입을 파라미터로 받는 생성자 2개를 만들 수 없는 경우
- public static 팩토리 메서드를 사용하는 것이 유용하다.
2. 반드시 새로운 객체를 만들 필요가 없다.
- 불변 클래스인 경우나 매번 새로운 객체를 만들 필요가 없는 경우에
- 미리 만들어둔 인스턴스 또는 캐시해둔 인스턴스를 변환할 수 있다.
- foo는 매번 새로운 객체를 리턴받게 된다.
- new Foo라는 코드가 호출될 때마다 새로운 인스턴스가 만들어진다.
- 하지만 원한다면 다음과 같은 방식은 GOOD_NIGHT 라는 Foo 객체만 반환이 된다.
- 미리 만들어준 인스턴스를 반환할 수 도 있다는 장점이 있다.
3. 리턴 타입의 하위 타입 인스턴스를 만들 수도 있다.
- 리턴 타입에는 인터페이스만 노출을 하고 실제 리턴하는 객체는 인터페이스의 구현체를 리턴하는 것
- 그러면 클라이언트 입장에서는 인터페이스만 가지고 코딩을 하게 된다.
- 실제 구현체는 모르게 되고 이는 매우 좋은 장점에 해당한다.
- 하나의 예로 java.util.Collections 가 그 예이다
- 구현체가 45개나 되는데 전부 non-public이다. 직접 그 구현체를 만들 수 없고 인터페이스를 통해서만 만들 수 있다.
- public으로 공개할 부담을 줄일 수 있고 클라이언트가 알아야 하는 개념적인 무게를 줄일 수 있다.
- 개념적인 무게 : 프로그래머가 인터페이스에서 제공하는 API를 사용할 때 알아야 할 개념의 개수와 난이도
- 자바 8부터는 인터페이스에 public static 메서드를 추가할 수 있게 되어있다. 따라서 Collections라는 클래스를 만들지
- 않고도 인터페이스 자체에 구현이 가능하다. Collections들이 가진 메서드들을 Collections 밑에 넣어도 되는 것
- private static 메소드는 자바 9부터 가능하다.
4. 리턴하는 객체의 클래스가 입력 매개변수에 따라 매번 다를 수 있다.
- static 메서드에서 리턴하는 객체는 하위 타입이 있다면 그 타입을 리턴해도 된다.
- 계속해서 유연성에 대해서 여러가지 방면으로 설명해주고 있다.
* private static 메소드가 필요한 이유?
- private static 메소드메서드 역시 private 메서드가 필요한 이유와 동일하다.
- 예로 public 메서드 안에서 scope 자체가 밖으로 노출될 필요가 없을 시
- private 한 메소드를 필요로 하게 되는데 public static 메서드 안에서 동일한 이유로
- private static 메서드가 쓰이게 된다.
5. 리턴하는 객체의 클래스가 public static 펙토리 메서드를 작성할 시점에 반드시 존재하지 않아도 된다.
- getFoo는 호출될 시점에 풀패키지 경로가 적힌 텍스트 파일에 뭐가 적혀있는지에 따라 다른 객체를 리턴하게 된다.
- 즉 이 메소드를 만들고 나서 다른 Foo타입의 클래스를 만들 수 있고 교체에서 쓸 수도 있다.
- 그 예가 JDBC 인데 getConnection이라는 썼을 때
- 실제 return 돼서 나오는 커넥션 객체는 DB 드라이버마다 다 다르다. mysql driver, h2 driver, oracle driver..
단점 1.
- public or protected 생성자 없이 static public 메서드만 제공하는 클래스는 상속할 수 없다.
- 따라서 Collections 프레임워크에서 제공하는 편의성 구현체는 상속할 수 없다. 오히려 경우나 상속 대신 컴포지션을 권장 하기에 장점이라 말할 수도 있다.
단점 2.
- 프로그래머가 static 팩토리 메서드를 찾는 게 어렵다.
- 생성자는 Javadoc 상단에 모아 보여주지만 static 팩토리 메서드는 Api 문서에서 특별히 다뤄주지 않고 따라서 문서 상단에 팩토리 메서드에 대한 문서를 제공하는 것이 좋다
참고 자료
'JAVA > Effective java' 카테고리의 다른 글
불필요한 객체를 만들지 말자 (0) 2021.01.01 리소스를 엮을 때는 의존성 주입을 선호하라 (0) 2020.12.31 private 생성자로 noninstantiability를 강제할 것 (0) 2020.12.30 private 생성자 또는 enum 타입을 사용해서 싱글톤으로 만들 것 (0) 2020.12.29 생성자 매개변수가 많다면 빌더 사용을 고려해보자 (0) 2020.12.28