모던 C++ 디자인 패턴 : 팩토리 패턴
팩토리 패턴 (Factory Pattern)은 객체를 생성하는 일을 전담하는 인터페이스 기법이다. 유연성과 확장성을 가져다 주니 잘 익혀두자.
예시로 자세히 알아보자. 아래의 Point
구조체는 2차원 상의 좌표를 나타내기 위해 x와 y를 입력 받아 객체를 생성한다. 한 가지 타입의 생성자만으로 구현된 간단한 예다.
이렇게 정의한 구조체에서 새로운 입력타입으로 Point
를 생성하고자 하거나, 두 가지 이상의 입력타입들로 생성해야 되는 구조체를 만드려면 어떻게 해야할까? 바로 이럴 때 팩토리 패턴을 사용하면 된다. 팩토리 패턴을 사용하면 유연성이 높아져 요구사항이 변경될 때 수정이 용이해지고, 확장성을 높여 새로운 입력타입 추가에 적은 비용이 든다.
위 Point
구조체에 새로운 입력타입 생성 요구사항이 발생했다고 상상해보자. 극좌표계 좌푯값 r과 theta를 입력 받아 이차원 좌표 x, y를 결정 짓는 생성자를 구현해야 한다. 기존 생성자를 수정하여 아래와 같이 변경할 수 있다. 아래는 그닥 좋지 않은 적용방법이다. 또, 입력 인자 이름을 중립적으로 작성하게 되어 직관적이지 못하며, 생성자 내 로직도 가독성이 떨어진다.
그럼, 팩토리 메서드를 적용해보자. 팩토리 메소드를 통해 입력타입 별 생성자 기능을 전담하는 메소드를 별도로 정의한다. 덕분에 사용자는 메소드명을 통해 어떤 동작을 하게 되는지 명확히 이해할 수 있으며, 입력인자로 어떤 값이 주어져야 하는지 더 잘 알 수 있다.
아래는 Point
구조체에 적용한 팩토리 메서드의 예이다. Point::NewCartesian(x,y)
처럼 팩토리 메서드를 통해 Point
객체를 생성할 수 있다. 또, 기존 생성자는 protected
를 통해 사용자가 의도하지 않은 방법으로 객체를 생성하는 것을 방지한다. 기존 요구사항이 변경되더라도 해당 팩토리 메소드만 유연하게 수정하면 되고, 신규 요구사항이 추가되더라도 Point::NewXXX()
처럼 팩토리 메소드를 추가하여 확장성도 얻을 수 있다.
별도의 팩토리 클래스를 정의하여 생성 기능을 담당하는 팩토리 메소드들을 분리할 수도 있다. PointFactory::NewCartesian(x,y)
처럼 객체를 생성할 수 있다. 앞서 소개한 팩토리 메소드처럼 사용자가 의도치 않은 방법으로 객체 생성하는 것을 방지하기 위해 Point
구조체의 생성자는 private
로 숨겼다.
소개한 방법 외에도 다양한 팩토리 패턴 적용 기법들이 더 있다. 기회가 된다면 또 정리해보겠다.