이펙티브 자바 3/E - 교보문고
프로그래밍인사이트 | 자바 6 출시 직후 출간된 『이펙티브 자바 2판』 이후로 자바는 커다란 변화를 겪었다. 그래서 졸트상에 빛나는 이 책도 자바 언어와 라이브러리의 최신 기능을 십분 활용
www.kyobobook.co.kr
개요
흔히 우리는 클래스의 인스턴스를 얻기 위하여 생성자를 사용한다.
- 생성자를 활용한 인스턴스 생성
class character{
int hp;
int mp;
character(int hp,int mp){
hp=this.mp;
hp=this.mp;
}
}
팩터리 메서드를 사용하기에 앞서 팩터리 메서드란 무엇일까?
클래스의 객체를 생성하는 메서드를 만들고 이를 static선언을 하여 인스턴스를 만드는 것이다.
- 정적 팩터리 메서드를 활용한 인스턴스 생성
class character{
int hp;
int mp;
character(int hp,int mp){
hp=this.mp;
hp=this.mp;
}
static character hp(int hp,int mp) {
return new character(hp,mp);
}
}
정적 팩터리 메서드의 장점
1. 이름을 가질 수 있다.
생성자는 무조건 클래스와 같은 이름을 가진다.
하지만 메서드는 이름을 지어줄 수 있어 객체의 특성을 더 쉽게 묘사할 수 있다.
public static void main(String[] args) {
//매개변수의 값이 무슨 역할인지 이해하기 힘들며 특성을 잘 나타내지 못합니다.
character ch1 = new character(5,5);
//매개변수의 값이 hp와mp라는 것을 잘 나타냅니다.
character ch2 = character.hp_mp(5, 5);
}
또한 생성자는 하나의 시그니처로는 하나의 생성자만을 만듭니다.
하지만 메서드는 이러한 제약이 없어 각각의 차이를 드러낼 수 있습니다.
static character warrior(int hp,int mp) {
return new character(hp,mp);
}
static character magican(int hp,int mp) {
return new character(hp,mp);
}
위의 두 메서드는 시그니처 제약이 없고 전사와 마법사를 만든다는 특성을 잘 표현해 준다.
2. 호출될 때마다 인스턴스를 새로 생성하지는 않아도 된다.
불필요한 객체 생성을 하는 것은 심한 메모리 낭비이다.
만약 클래스의 멤버 변수가 1억개 라고 해보자.
클래스의 객체를 자주 사용한다면 사용할 때마다 객체를 생성하여 1억 개의 대입 연산을 하게된다.
팩터리 메서드를 활용하여 인스턴스를 미리 만들어 놓고 메서드로 호출하여 불필요한 연산을 피할 수 있다.
class character{
int hp;
int mp;
//master 인스턴스를 미리 생성한다.
private static final character master = new character(50,50);
character (int hp, int mp) {
this.hp=hp;
this.mp=mp;
}
// 만들어져 있는 master 인스턴스를 반환시켜준다.
static character getmaster() {
return master;
}
}
3. 반환 타입의 하위 타입 객체를 반환할 수 있는 능력이 있다.
반환할 객체의 클래스를 자유롭게 선택하는 유연성이 생긴다.
사용자는 이러한 유연함으로 알아야할 개념의 수와 난이도가 낮아진다.
class character{
static wizard type(int i) {
//wizard인터페이스를 구현한 flame과 eletric 을 반환한다.
if(i==1)
return new flamewizard();
else
return new eletricwizard();
}
}
flame과 eletric을 몰라도 프로그래머는 인터페이스대로 동작할 객체임을 알기에 굳이 안찾아 봐도 된다.
4. 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
위의 3번과 같은 맥락이라 생각한다. 위의 코드는 매개변수 i에 따라 클래스의 객체를 반환하며 i값은 달리하여 필요한 클래스의 객체를 반환시킨다.
5. 정적 팩터리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
아직 이부분은 잘 모르겠다.
정적 팩터리 메서드의 단점
1. 상속을 하려면 pulbic이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
만약 부모클래스의 생성자가 private이면 자식 클래스는 정적팩터리 메서드만 제공받아 활용할 수 없다.
2. 정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
메서드이기 때문에 다른 메서드들과 구분하여 정적 팩터리 메서드 방식 클래스를 인스턴스화할 방법을 알아내야 한다. 이러한 문제를 완하하기 위하여 널리 알려진 규칙에 따라 정적 팩터리 메서드를 명명한다.
| 이름 | 설명 |
| from | 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환하는 형변환 메서드 |
| of | 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환하는 집계 메서드 |
| valueOf | from과 of의 더 자세한 버전 |
| instance 혹은 getInstance |
(매개변수를 받는다면) 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스임을 보장하지는 않는다. |
| create 혹은 newInstance |
instance 혹은 getInstance와 같지만, 매번 새로운 인스턴스를 생성해 반환함을 보장한다. |
| getType | getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 쓴다. "Type"은 팩터리 메서드가 반환할 객체의 타입이다. |
| newType | newInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 쓴다. "Type"은 팩터리 메서드가 반환할 객체의 타입이다. |
| type | getType과 newType의 간결한 버전 |
'book > Effective java' 카테고리의 다른 글
| [Effective java] item2 생성자에 매개변수가 많다면 빌더를 고려하라 (0) | 2021.08.31 |
|---|