지난 포스팅에서는 객체 생성을 캡슐화하여 서브클래스에게 위임하는 팩토리 메소드 패턴에 대해 알아보았다. 이번에는 객체 생성을 추상 인터페이스를 통해 캡슐화하여 일련의 제품들을 공급할 수 있는 추상 팩토리 패턴에 대해 복습한다.

정의

주로 제품군을 만들 때 쓰는 패턴으로 인터페이스를 이용하여 서로 연관된, 또는 의존하는 객체를 생성한다. 추상 팩토리 패턴을 사용하면 추상화된 인터페이스를 통해서 일련의 제품들을 제공받을 수 있다. 팩토리를 사용하는 클라이언트는 실제로 어떤 제품이 생산되는지 알 필요가 없다. 추상화된 인터페이스로부터 다시 추상화된 제품을 받아서 추상화된 기능만 사용하면 된다. 결국 클라이언트와 팩토리에서 생산되는 제품이 분리된다.

다이어그램

모든 구상 팩토리들이 구현해야 하는 추상 팩토리 인터페이스를 정의한다. 추상 팩토리에서는 일련의 제품을 생산하기 위한 메소드를 정의하고 구상 팩토리는 이를 구현한다. 구상 팩토리를 2개로 나눈 이유는 제품이 두 개의 제품군으로 이루어져있기 때문이다. 구상 팩토리마다 다른 일련의 제품군을 생산하기 때문에 구상 팩토리 가운데 적당한 팩토리를 골라서 사용하면된다.

예시

추상 팩토리의 용도는 일련의 제품군을 생산하는데 사용하는데 있다. 지상 유닛을 만들기 위해 일련의 재료들이 필요하다고 가정하자. 재료는 옷, 무기로 분류된다. 옷은 화생방보호의, 우주복와 간호복 3종류가 있으며 무기는 총, 화염 방사기, 치료기 3종류가 있다.

팩토리는 해당 유닛의 제품군을 생산한다. Marine 팩토리는 Spacesuit와 Gun을 Firebat 팩토리는 CBR과 FlameThrower을 Meidc 팩토리는 NursingWear와 Curer을 생산한다. 각 유닛마다 무기와 옷이 혼동되지 않도록 올바른 규격을 제공하는 것이 가능하고 유연하게 일련의 재료를 생산할 수 있다. 재료의 생산이 완료되면 유닛을 생산하여 반환하게끔 한다.

팩토리 메소드 패턴 vs 추상 팩토리 패턴

두 패턴 모두 애플리케이션을 특정 구현으로부터 분리시키는 역할을 맡고있다

추상 팩토리 패턴 뒤에는 팩토리 메소드 패턴이 숨어있는 것인가?

추상 팩토리는 일련의 제품들을 생산하기 위한 인터페이스를 정의한다. 제품을 생산하기 때문에 메소드가 팩토리 메소드로 구현되는 경우도 있다. 그러한 팩토리 메소드는 구상 제품을 생산하는 일을 맡고 있고, 추상 팩토리의 서브클래스를 만들어서 각 메소드의 구현을 제공한다.

팩토리 메서드 패턴은 클래스를 써서 제품을 만들고 추상 팩토리 패턴에서는 객체를 써서 제품을 만든다.

팩토리 메서드 패턴은 클래스 상속을 통해서 객체를 만들지만 추상 팩토리 패턴은 객체 구성을 통해서 객체를 만든다.

팩토리 메서드 패턴을 통해 객체를 생성할 때는 클래스를 확장하고 팩토리 메소드를 오버라이드 해야 한다.

팩토리 메서드 패턴은 서브클래스를 통해서 객체를 만들기 위한 패턴이기 떄문에 클라이언트는 자신이 사용할 추상 형식만 알면 된다. 이는 클라이언트와 구상 형식을 분리시켜준다.

추상 팩토리 패턴에서는 제품군을 만들기 위한 추상 형식을 제공한다.

제품이 생산되는 방법은 이 형식의 구상클래스에서 제공한다. 팩토리를 이용하고 싶으면 일단 팩토리의 인스턴스를 만든 다음 추상 형식을 써서 만든 코드에 전달하면 된다. 클라이언트와 구상 제품이 분리되며 일련의 연관된 제품을 하나로 묶을 수 있는 장점이 있다.

추상 팩토리 패턴에서 제품군에 제품을 추가하면서 제품군을 확대해야 하는 경우, 인터페이스를 바꿔야한다.

반면, 팩토리 메소드 패턴에서는 한가지 제품만 생산하기는 하지만 복잡한 인터페이스가 필요하지 않고 메소드도 하나만 있으면 된다.

팩토리 메소드 패턴은 클라이언트의 코드와 인스턴트를 만들어야할 구상 클래스를 분리시켜야하거나 어떤 구상 클래스를 필요로 하게 될지 미리 알 수 없는 경우에 사용한다.

추상 팩토리 패턴은 클라이언트에서 서로 연관된 일련의 제품들을 만들어야 하는 경우에 사용한다. 두 패턴 모두 객체 생성을 캡슐화해서 애플리케이션의 결합을 느슨하게 만들고, 특정 구현에 대한 의존성을 줄여주기 때문에 용도에 따라 적절한패턴을 사용하면 된다.

추상 팩토리 패턴 예제