< effective java 3편과 백기선님의 youtube 강의를 토대로 쓴 글입니다. >
지난 시간에 했던 내용
-
점층적 생성자 패턴 : 매개변수가 0~N개까지 모두 선언해서 사용하는 것
-
자바빈즈 패턴 : 매개변수 없는 생성자로 객체 만들고, setter를 사용하는 것
-
빌더 패턴 : 클라이언트 코드에서 필요한 객체를 직접 생성하는 대신, 그 전에 필수 인자들을 전달하여 빌더 객체를 만든 뒤, 빌더 객체에 정의된 설정 메서드들을 호출하여 인스턴스를 생성하는 것
오늘의 주제 - 생성자 대신 정적 팩터리 메서드를 고려하라. (static factory method)
정적 팩터리 메서드란 무엇인지 코드를 보면서 알아보자.
<코드 1.>
public class Person {
private String name;
private int age;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getAge() { return age; }
public void setAge(int age) { this.age = age; }
private Person(){ }
public static Person newPerson(){
return new Person();
}
public static void main(String[] args) {
Person conatuseus=Person.newPerson();
}
}
위와 같이 생성자가 있고, public static인 newPerson 메서드가 있다.
newPerson 메서드는 Person 객체를 생성해서 반환한다.
main에서 Person 객체를 “Person.newPerson()” 이렇게 생성할 수 있다.
이렇게 정적 팩터리 메서드는 public static 팩토리 메서드를 사용해서 해당 클래스의 인스턴스를 만드는 방법이다.
쉽게 말해서 객체를 생성하는 메서드를 만들고, static으로 선언하는 기법이다.
장점
1. 이름을 가질 수 있다.
생성자에 넘기는 매개변수와 생성자 자체만으로는 반환될 객체의 특성을 제대로 설명하지 못한다.
반면 정적 팩터리는 이름만 잘 지으면 반환될 객체의 특성을 쉽게 묘사할 수 있다.
<코드 1>에서 Person클래스에 다음과 같은 메서드를 추가했다고 생각해보자.
public static Person withName(String name){
Person p=new Person();
p.setName(name);
return p;
}
이 메서드를 사용하면 main에 Person 객체를 생성할 때 다음과 같이 생성할 수 있다.
Person firstPerson=Person.withName(“conatuseus”);
객체를 생성하는 위의 코드만 보더라도 이름이 conatuseus인 Person이라는 것을 알 수 있다. 따라서 사용하기 쉽고, 읽기 편하다.
또, 생성자는 시그니처에 제약이 있다.
똑같은 타입을 파라미터로 받는 생성자를 두 개 만들 수 없다. 이런 경우에도 public static 팩토리 메서드를 사용하는 것 유용하다.
public Person(String name){
this.name=name;
}
public Person(String address){
this.address=address;
}
위와 같이 똑같은 타입을 파라미터로 받는 생성자 같이 만들 수 없다.
따라서 이것을 public static 팩토리 메서드로 만들어보면 다음과 같다.
public Person withName(String name){
Person p=new Person();
p.setName(name);
return p;
}
public Person withAddress(String address){
Person p=new Person();
p.setAddress(address);
return p;
}
2. 반드시 새로운 객체를 만들 필요가 없다.
불변(immutable) 클래스인 경우나 매번 새로운 객체를 만들 필요가 없는 경우에 미리 만들어둔 인스턴스 또는 캐시해둔 인스턴스를 반환할 수 있다.
방법은 다음과 같다.
public static final Person person=new Person();
public static Person getPerson(){
return person;
}
public static final로 person 인스턴스를 생성해놓고 public static 메서드인 getPerson으로 가져다가 쓰는 것이다.
3. 반환 타입의 하위 타입 인스턴스를 만들 수 있다.
public class Person {
private String name;
private int age;
private String address;
private Person(){}
static class Student extends Person{
}
static class Teacher extends Person{
}
public static Person getStudent(){
return new Student();
}
public static Person getTeacher(){
return new Teacher();
}
public static void main(String[] args) {
Person conatuseus=Person.getStudent();
Person dynamiseus=Person.getTeacher();
}
}
이 코드에서 Student, Teacher 클래스는 Person의 하위 타입이다.
main에서 conatuseus는 Student 타입 인스턴스이고, dynamiseus는 Teacher 타입 인스턴스이다.
이 능력은 반환할 객체의 클래스를 자유롭게 선택할 수 있게 하는 ‘엄청난 유연성’을 가진다.
4.입력 매개변수에 따라 매번 다른 클래스의 객체를 반환할 수 있다.
3번 장점과 같은 이유로 객체의 타입이 다를 수 있다. 매개변수에 따라 선택적인 Sub class 객체를 반환할 수 있다.
이 예는 Enum을 자세히 공부하고 다시 적어보자.
단점.
정적 팩터리 메서드는 프로그래머가 찾기 어렵다.
'Java' 카테고리의 다른 글
점층적 생성자 패턴, 자바빈즈 패턴, 빌더 패턴 (0) | 2019.03.13 |
---|---|
Annotation (어노테이션) (0) | 2018.11.13 |