들어가기에 앞서...
필자는 자바 웹 개발자로 근무한지 2년 차인데 자바에 대해서 더욱 효율적으로 사용하고 싶어 해당 서적을 구매하였다.
공부한 내용은 블로그에 포스팅하며 정리하는 식으로 진행할 예정이다.
Q. 이펙티브자바를 선택한 이유?
A. 워낙 유명한 책 중 하나이며, 자바 개발자라면 필수 서적이라는 주변 개발자 지인들의 강력한 추천으로 구매하게 되었다.
이 포스팅에서 작성하는 내용은 EFFECTIVE JAVA(이펙티브자바) 에서 발췌하였습니다.
아이템 1. 생성자 대신 정적 팩토리 메서드를 고려하라.
자바에서 객체를 생성할 때 public 생성자를 이용하는 방법도 있지만 정적 메서드 팩토리를 이용하면 더욱 효율적으로 사용할 수 있다.
물론, 정적 팩토리 메서드에도 단점은 존재한다.
- 정적 팩토리 메서드란?
객체 생성을 해주는 메소드(Method)라고 이해하면 된다.
아래의 코드처럼 boolean 변수를 받아서 박싱 클래스로 반환해주는 것으로 예를 들 수 있다.
정적 팩토리 메서드 내에서 생성자를 사용하는 것은 상관없고, 정적 팩토리 메서드를 호출하는 것이 아닌 생성자를 호출하는 것은 정적 메서드 팩토리를 사용하는 것이 아니다.
(참고로, 디자인 패턴의 팩터리 패턴과는 별개이다.)
// ex1
public static Boolean valueOf(boolean b){
return b ? Boolean.TRUE : Boolean.FALSE;
}
// ex2
public class Game{
private String name;
private Game(String name){
this.name = name;
}
// 아래처럼 생성자를 이용해서 생성 및 반환해줄 수도 있다라는 걸 보여주기위한 예
public static Game createGame(String name){
return new Game(name);
}
}
정적 팩토리 메서드의 장점
1) 용도에 따라 이름을 설정할 수 있다.
생성자의 경우 new 클래스명으로 생성하기 때문에 특별한 이름을 갖지 못한다.
하지만 정적 팩토리 메서드를 사용하면 메서드 이름을 이용하여 무슨 용도를 위한 메서드인지 알려줄 수 있다.
또한, 생성자는 만들 수 있는 것에 한계가 있지만 정적 팩토리 메서드의 경우 이름만 달리하면 이러한 제약이 없다.
2) 호출될 때마다 메서드에서 인스턴스를 새로 생성하지 않아도 된다.
enum 같은 클래스는 인스턴스를 미리 만들어 놓거나 새로 생성한 인스턴스를 캐싱하여 재활용하는 식으로 불필요한 객체 생성을 막을 수 있다.
3) 하위 타입 객체를 반환할 수 있으며, 입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
반환하는 객체의 하위 타입을 반환하여 유연성을 제공할 수 있다.
Fps, Rpg 클래스가 Game 클래스를 상속받는다고 가정하면 아래의 코드처럼 하위 타입을 반환할 수 있다.
public class Game{
...
public static Game of(String name){
if("FPS".equals(name)){
return new Fps();
}
else if("RPG".equals(name)){
return new Rpg();
}
else{
return new Game();
}
}
}
4) 정적 팩토리 메서드를 작성하는 시점에는 반환할 객체의 클래스가 존재하지 않아도 된다.
정적 팩토리 메서드의 단점
1) 상속을 하려면 public 이나 protected 생성자가 필요하니 정적 팩터리 메서드만 제공하면 하위 클래스를 만들 수 없다.
2) 정적 팩토리 메서드는 다른 사용자가 찾기 어렵다.
생성자나 자바 API 설명에 드러나있지 않고 개발자가 네이밍해서 메소드를 정의하기 때문에 찾기 어렵다는 단점이 있다.
정적 팩토리 메서드에서 흔히 사용하는 명명 방식
- from : 하나의 매개변수를 하나 받아서 해당 타입의 인스턴스를 반환
- of : 여러 매개변수를 받아 적합한 타입의 인스턴스를 반환
- valueOf : from과 of의 더 자세한 버전
- instance | getInstance : 매개변수로 명시한 인스턴스를 반환하지만, 같은 인스턴스가 아닐 수도 있음
- create | newInstance : 매개변수로 명시한 인스턴스를 새로운 인스턴스를 생성해 반환
- getType : getInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 사용
- newType : newInstance와 같으나, 생성할 클래스가 아닌 다른 클래스에 팩터리 메서드를 정의할 때 사용
- type : getType과 newType의 간결한 버전
정리
정적 팩터리 메서드와 public 생성자는 각각 장단점이 있으니 상황에 맞게 사용하는 것이 좋다.
하지만, 정적 팩터리 메서드를 이용하는 게 효과적인 경우가 많다.
'BE > Java' 카테고리의 다른 글
[Effective Java] 아이템 3. private 생성자나 열거 타입으로 싱글턴임을 보장하라. (0) | 2022.08.31 |
---|---|
[Effective Java] 아이템 2. 생성자에 매개변수가 많다면 빌더를 고려하라. (0) | 2022.08.30 |
[Spring Security] JSON 요청 시, 정상 작동하지 않는 오류 해결 (0) | 2022.07.05 |
[Java] Runnable Jar file로 export 시 목록에 없는 경우 (0) | 2022.05.28 |
[오류 해결] Xml 파싱 시, 유니코드 문자 치환하기 (0) | 2022.05.10 |