Move Creation Knowledge to Factory (110)
02 Jul 2021 | DesignPattern Refactoring개요
어떤 클래스의 인스턴스를 생성하는 데 사용되는 데이터와 코드가 여러 클래스에 퍼져있다면,
그 생성 지식을 하나의 팩터리 클래스로 옮긴다.
동기
객체 생성을 위한 지식이 여러 클래스에 퍼져 있을 때, 이를 문어발 생성 이라고 한다. 이 것은 객체 생성과 상관 없는 클래스가 그 책임의 일부를 맡고 있음을 뜻한다.
예를 들어 클라이언트가 주어진 외부 설정값에 맞춰 객체의 상태를 조정할 필요가 있지만, 그 객체의 생성을 담당하는 코드에는 쉽게 접근할 수 없는 경우를 생각해보자. 클라이언트에서 객체 생성 코드에 쉽게 접근할 수 없다면 클라이언트가 어떻게 그 객체의 상태를 조정할 수 있을 것인가? 보통은 무식한 방법으로 해결한다. 클라이언트는 외부 설정값을 한 객체에 전달하고, 이를 또 다른 객체로, 결국에는 생성 코드까지 계속 전달하는 것이다. 이렇게 하는 것이 가능은 하지만, 생성 코드와 데이터가 여러 곳에 퍼지는 문제가 있다.
이 경우 Factory 패턴이 도움이 된다. 팩토리 인스턴스가 런타임에서 계속 재사용되며 추가기능을 부여할 수도 있다.
장점
- 생성 로직과 외부 설정값 처리 로직을 한 곳으로 모은다.
- 생성 로직으로부터 클라이언트를 분리한다.
단점
- 직접 생성으로도 충분한 경우라면, 괜히 설계만 복잡하게 한다.
절차
이 절차는 팩터리를 인터페이스가 아닌 클래스로 구현한다고 가정한다. 다른 클래스에서 구현할 팩터리 인터페이스가 필요하다면, 이 절차를 조금 수정해야 한다.
-
주어진 클래스의 인스턴스를 생성하기 위해 다른 클래스와 협력하는 클래스를 찾는다. 이런 클래스를 생성 클래스라 하고 인스턴스로 만들어지는 클래스를 대상 클래스 라고 하자. 만약 생성 클래스가 대상 클래스의 인스턴스를 만들 때 생성 메서드를 통하지 않는다면 필요할 경우 생성 클래스나 대상 클래스를 수정해 생성 메서드를 사용하도록 한다.
-
팩터리로 사용할 클래스를 만드는데, 그 이름은 대상 클래스를 고려하여 짓는다
-
Move Method 리팩터링을 적용해 생성 메서드를 팩터리 클래스로 옮긴다. 생성 메서드가
static
이라도 옮긴 후에는 인스턴스 메서드로 바꿀 수 있다. -
팩터리의 인스턴스를 만들고, 이를 통해 대상 클래스의 인스턴스를 얻도록 생성 클래스를 수정한다.
-
다른 클래스의 데이터와 메서드가 여전히 생성 작업에 사용되고 있을 수 있다. 무엇이든 팩토리에 있는 것이 더 나아보인다면 팩토리로 옮겨 더 많은 기능을 담당하게 할 수 있다.