티스토리 뷰
최근 이펙티브 자바 3판 1 회독을 끝냈다
다른 사람들의 리뷰, 후기를 보면 책 수준이 굉장하다는데 나도 동감한다
개인적으로 책을 볼 때 1회독은 빠르게 흐름을 잡고 2-3 회독하면서 깊게 이해하는 편이라
야무진 책 내용을 기억에 오래 붙잡아두기 위해 정리해보고자 한다
책 내용을 훑는데 그치지 않고 한 발자국 더 나아가 개인적인 의문점에 대해 찾아보고 정리해야겠다
아이템 1의 핵심 내용은 new 연산자를 사용해 클래스를 생성하는 코드 대신 static factory method를 사용하라는 것이다
왜 그래야 할까?
장점은 다음과 같다
1. new Class() 대신 이름을 가진 메서드로 호출할 수 있다
2. 호출될 때마다 인스턴스를 생성할 필요가 없다
3. 반환 타입의 하위 타입 객체를 반환할 수 있다
4. 입력 매개변수에 따라 다른 클래스의 객체를 반환할 수 있다
5. static factory method 작성하는 시점에는 반환될 객체의 구체 클래스가 존재하지 않아도 된다
new 어쩌구저쩌구() 대신 이름을 가진 메서드를 사용하면 뭐가 좋을까?
변수명을 예쁘게 짓는 것과 일맥상통한데 코드를 실행하는 컴퓨터가 아닌
코드를 읽는 사람이 더 쉽게 받아들일 수 있도록 돕는다
돌아가는 프로그램을 만들기는 쉬우나 이해하기 쉬운 프로그램을 만드는 것은 어렵다
소프트웨어 생명주기 중 코드를 작성하는 시간보다 코드를 읽고 수정하는 시간이 더 많으니 이는 분명한 장점이 될 수 있다
반환 타입의 하위 타입을 왜 반환할까?
Java9부터 사용 가능한 List.of() static factory method를 살펴보면
List는 interface인데 반환 타입으로 다음과 같은 객체가 반환된다
java.util.ImmutableCollections$ListN
static factory method를 사용하면 구현부가 캡슐화되면서 한눈에 파악하기 힘들 수 있다
이 부분에서의 핵심은 변경에 유연하게 대응할 수 있다는 점이다
만약 자바의 다음 릴리즈에서 List.of()로 반환되는 구현체를 바꾸더라도
static factory method를 사용한 코드는 변경할 필요 없이 최적화된 코드로 인한 성능 이점을 누릴 수 있다
new List12(); 처럼 작성했다면 List12()를 모든 코드에서 변경해주거나 최적화의 이점을 누리지 않으면 된다
H/W 성능이 점점 좋아지면서 이 부분에서 차이를 크게 못 느낄 수 있으나 대규모로 갈수록 성능 차이는 심해질 수 있다
또한 다음 릴리즈 뿐만 아니라 계속해서 이어질 버전 업그레이드를 생각한다면 유연하게 대응할 수 있는 코드가 필수적이다
입력 매개변수가 달라지면 인스턴스를 어떻게 생성할까?
Telescoping Constructor Pattern 점층적 생성자 패턴이라는 방식이 존재하는데 이름은 거창하나 까고 보면 별게 아니다
(a)를 받는 생성자 / (a, b)를 받는 생성자 / (a, b, c)를 받는 생성자, 이와 같이 생성자 오버로딩일 뿐이다
프로그램은 계속해서 변화한다 매개변수를 100개 받으면 어떻게 될까?
이 때는 생성자 오버로딩을 하드코딩에 미친 사람이 아니라면 할 수 없을 것이다
Builder Pattern을 이용해 쪼개서 받을 수 있을 것이고 이와 동시에 많은 생성자 중 특히 더 자주 쓰이는 녀석들을
의미 있는 이름을 가지는 static factory method로 만들 수 있다
매개변수가 많은 경우에는 매개변수를 다 나열하는 생성자보다 특별한 이름을 가진 팩토리 메서드가 더 파악하기 쉽다
static factory method를 작성하는 시점에는 구체 클래스가 존재하지 않아도 된다?!
구체 클래스가 아예 존재하지 않아도 되는 것이 아니라 실제 애플리케이션 돌릴 때의 최종본이 없어도 된다는 것이다
개발 독립성을 위해 필요한 기법으로써 통합 전에는 임시 객체를 이용하면 된다
단점은 다음과 같다
1. 상속을 위해서는 public / protected 생성자가 필요하다
2. 대규모 프로그램의 경우 흐름 파악이 한눈에 들어오지 않을 수 있다
첫 번째, 생성자를 private으로 막아두고 static factory method를 사용할 때의 단점이다
이 제약은 상속보다 합성을 사용하도록 유도하기 때문에 오히려 좋을 수 있다
두 번째, 생성자를 대체하기 때문에 일반 메서드와 구분이 잘 안 갈 수도 있고
어떻게 생성하는지 factory method를 까 봐야 알 수 있다
API 문서를 주의해서 작성하고 관례에 따라 네이밍하여 파악에 도움을 주어야 한다
프로그래밍은 트레이드오프의 연속이다
장점이 많다고 해서 무조건 static factory method를 사용해야 하는 것은 아니다
장단점을 고려해서 필요하다면 사용하도록 하고, 필요 없는 부분까지 모두 static factory method를 사용하지는 말자
오픈소스를 만들거나 자신만의 프로젝트를 만드는게 아닌 이상 항상 개발 공수가 먼저다
비즈니스에 어떤 가치를 더할 수 있는지 고민해서 사용하자
'Java > Effective Java' 카테고리의 다른 글
[Item06] 재사용으로 성능 향상 시켜보자 (0) | 2022.02.10 |
---|---|
[Item05] 때려박는 코딩은 그만, 확장성을 고려하자 (0) | 2022.02.08 |
[Item04] 인스턴스화 방지, setter 막아두기 과연 옳은가 (0) | 2022.02.05 |
[Item03] 싱글턴이 왜 필요할까? (0) | 2022.02.02 |
[Item02] Builder Pattern의 장단점은 무엇인가 (0) | 2022.01.28 |