팩토리 메서드(Factory Method)는 객체의 생성을 캡슐화 하는 패턴이다. 이 패턴은 어떤 클래스의 인스턴스를 생성할지를 서브클래스에서 결정하도록 한다. 생성된 객체의 유형을 변경하기가 쉬워지고, 생성된 객체를 사용하는 클라이언트 코드는 어떤 구체적인 클래스의 인스턴스가 생성되는지에 대해 알 필요가 없다.
팩토리 메서드 패턴의 주요 구성 요소는 다음과 같다.
이러한 팩토리 메서드는, 객체 생성에 대한 책임을 하위 클래스로 미루어서 유연성을 제공한다. 하위 수준 모듈을 확장하고자 할 때 매우 유용하다.
다음은, C++ 코드 예제이다.
#include <iostream>
#include <string>
// Product
class Document {
public:
virtual std::string operation() const = 0;
virtual ~Document() = default;
};
// ConcreteProduct
// Document의 구현체가 되어야 한다.
class TextDocument : public Document {
public:
std::string operation() const override {
return "TextDocument operation";
}
}
class PDFDocument : public Document {
public:
std::string operation() const override {
return "PDFDocument operation";
}
}
// Creator
// Product 인스턴스를 생성한다.
class DocumentCreator {
public:
virtual Document* factoryMethod() const = 0;
virtual ~DocumentCreator() = default;
// operation() 메서드는 Creator로 생성된 product가 무엇인지 출력
// 이때, virtual로 선언된 factoryMethod()를 ConcreteCreator에서 구현.
std::string operation() const {
Document* product = factoryMethod();
return "Creator: " + product->Operation();
}
}
// ConcreteCreator
// Create를 구현한다.
class TextDocumentCreator : public DocumentCreator {
public:
Document* factoryMethod() const override {
return new TextDocument();
}
}
class PDFDocumentCreator : public DocumentCreator {
public:
Document* factoryMethod() const override {
return new PDFDocument();
}
}
// Client
// ClientCode는 ConcreteCreator의 참조를 인자로 받는것이 아닌, 상위 클래스인
// Creator의 참조를 인자로 받는다. (구현체들을 모두 받을 수 있다.)
void clientCode(const DocumentCreator& creator) {
std::cout << creator.operation() << std::endl;
}
int main()
{
TextDocumentCreator textCreator;
PDFDocumentCreator pdfCreator;
clientCode(textCreator);
clientCode(pdfCreator);
return 0;
}
##출력
"Creator: TextDocument Operation"
"Creator: PDFDocument Operation"