본문 바로가기

Library/C/C++

개체 팩토리를 사용해야 할 때, 그렇지 않을 때

일반적으로, 개체를 생성하는 하나의 함수가 연관된 모든 자료형을 알고 있어야 한다면 이것은 심각한 컴파일 과정의 종속 관계를 유발한다. 고만고만한 규모의 프로젝트라도 컴파일 종속 문제가 심각해진다면, 이것은 전체 프로젝트의 생산성을 크게 떨어뜨리게 된다. 클린 빌드가 시간이 오래 걸리는 것은 그렇다고 하더라도, 작은 수정 하나가 연달아 다른 부분까지 재컴파일을 발생시킨다면, 아주 작은 버그 하나 수정하는 것도 복잡한 일이 될 수 있다. 이런 끔찍한 일을 경험해보지 않았다면, 이것이 얼마나 심각한 문제인지 체감하기 어려울 것이다.

디자인 패턴의 팩토리 메서드는 개체 생성과 관련된 이런 문제를 다루고 있다. 팩토리 메서드와 같은 패턴이 꼭 컴파일 종속성 문제에만 대응되는 것은 아니지만, Interface / Implementation 분리로서는 대응하기 곤란한 개체 생성에 관련된 중요한 기법이다. 팩토리 메서드는 생성 책임을 개체를 생성하려는 행위자에게 넘기는 방식으로 디자인의 복잡도를 떨어뜨린다. 이 경우, 생성하는 개체의 기본 자료형을 서로가 알고 있어야 하며, 생성된 개체는 동적 바인딩을 활용하여 동작하게 된다. 즉, 하나의 거대한 생성 함수가 생성하려는 모든 개체를 알고 있음으로 인해 발생하는 컴파일 종속성을 피해갈 수 있는 부수적인 효과도 발생한다.

팩토리 메서드와 같은 생성 전략은 생성하고자 하는 개체가 단순한 자료형이 아닌, 개체로서의 동작이 강조되는 경우에는 매우 훌륭한 방법이다. 그러나, 개체의 동적인 행위보다 명시적인 개체 생성이 더 중요하다면, 팩토리 메서드는 적당한 방법이 아니다. 즉, 생성하고자 하는 개체가 단순한 자료형이고, 한 두 파일에만 정의가 존재한다면, 팩토리 메서드는 오히려 문제를 필요 이상으로 복잡하게 만든다.

예를 들어, 전체 정의가 몇 줄 되지 않는 단순한 자료형을 생성하는데 개체 팩토리를 사용한다고 해보자. 개체 팩토리는 양쪽 모두가 알고 있는 기반 자료형으로 돌려주기 때문에 이런 단순한 자료형도 기반 클래스를 상속해야 한다. 또, 생성된 기반 클래스로부터 명확한 자료형을 알아내기 위해, 어쩔 수 없이 생성하고자 하는 개체의 정의를 참조해야 한다. 이것은 개체 팩토리를 사용하면서 피하고자 했던 문제들이다. 즉, 개체 팩토리를 사용해서 피하고자 했던 문제들이 그대로 재현되는 셈이다.

결론적으로 말하자면, 개체 팩토리는 동적 바인딩이 중요한 개체를 생성하는데 적합한 방법이다. 보통 이런 개체들은 단순한 자료형이라기 보다는 개체로서의 특징이 더 두드러지며, 정의와 구현은 파일 단위이기 마련이다. 이런 경우, 팩토리 메서드는 컴파일 종속성 문제를 피할 수 있고, 생성 책임을 행위자에게 넘길 수 있다. 그러나, 명확한 개체 생성이 중요하고, 이들 개체가 상대적으로 작은 크기이며, 소수의 파일에 정의가 존재한다면 팩토리 메서드는 전통적인 개체 생성 방법에 비해 큰 장점이 없다.