Java는 호환성이 아주 좋은 언어로, 다양한 곳에 많이 쓰이고 있습니다. Spring, MapReduce, Apache-Storm, 등 많은 곳에 Java를 사용하고 있는데요, 이렇게 많이 사용하는 만큼 Java에 대한 강의도 많고, 공개되어 있는 코드들도 아주 많습니다.
이런 Java 코드를 작성할 때 유지보수하기 편하고 협업하기 편한 형태의 코드, 즉 좋은 패턴의 코드를 작성하려면 어떤 패턴을 따라야 하는지 알아보도록 하겠습니다.
- 무작정 Constructor를 사용하는 대신 static method를 활용하여 Factory method를 제공해보자!
Constructor는 따로 이름을 지정할 수 없을 뿐 더러, Constructor가 여러개라면 사용자가 클래스 구현 코드를 직접보거나 관련 문서를 읽지 않으면 사용하기 어렵습니다.
또한 어떤 상황이든 정해진 클래스의 인스턴스만 반환할 수 있기 때문에 매우 불편합니다.
Static factory method를 이용하면 적절한 이름을 할당하여 가시성을 높일 수 있고, 상황에 따라 매번 다른 클래스(클래스들이 상속하는 상위 객체를 반환하는 식으로)의 객체를 반환할 수도 있습니다.
따라서 Constructor 보다는 static method를 활용하여 객체를 Return하게 해주는 형태의 패턴을 사용합시다.
단점 : static factory method만 제공하면 상속을 할 수 없다.
2. Builder를 활용하자!
만약 클래스의 멤버 변수가 엄청 많은데, 매 상황에 따라 초기화가 필요한 멤버 변수가 달라진다면? 기존 constructor 또는 static method를 사용한다면 매 케이스마다 메소드를 overloading 해주어야 합니다.
그렇다고 객체를 생성해놓고 setter를 이용하여 필요한 것만 값을 넣어주자니 Thread safe한 구문을 작성하는 것이 너무 어렵습니다. (set를 여러번 부르는 중간에 컨텍스트 스위치가 일어난다면…?)
public class MyClass {
private final int member1;
private final int member2; public static class Builder {
private final int member1 = 0;
private final int member2 = 0; public Builder() {
} public Builder member1(int member1 val)
{member1 = val; return this;} public Builder member2(int member1 val)
{member1 = val; return this;} public MyClass build(){ return new MyClass(this); }
}
private MyClass(Builder builder) {
member1 = builder.member1;
member2 = builder.member2;
}
}
위와 같이 코드를 작성하면
new MyClass.Builder().member1(1).member2(2).build(); 와 같은 형태로 인스턴스를 만들 수 있습니다.