GoF Design Pattern(1) - 생성, 클래스, Factory Method

kimseyoung·2023년 12월 19일

Factory Method

팩토리 메서드(Factory Method)는 객체의 생성을 캡슐화 하는 패턴이다. 이 패턴은 어떤 클래스의 인스턴스를 생성할지를 서브클래스에서 결정하도록 한다. 생성된 객체의 유형을 변경하기가 쉬워지고, 생성된 객체를 사용하는 클라이언트 코드는 어떤 구체적인 클래스의 인스턴스가 생성되는지에 대해 알 필요가 없다.

팩토리 메서드 패턴의 주요 구성 요소는 다음과 같다.

  1. Product: 팩토리 메서드로 생성될 객체에 대한 인터페이스
  2. ConcreteProduct: Product의 구현체로서 실제로 생성될 객체.
  3. Creator: 팩토리 메서드를 정의하는 인터페이스를 제공한다. 이 인터페이스는 팩토리 메서드를 통해 객체를 생성한다. Creator 클래스는 Product에 대한 인터페이스를 사용하여 객체를 조작하는 클라이언트 코드를 작성한다.
  4. ConcreteCreator: Creator를 상속받아 실제로 객체를 생성하는 구체적인 클래스, 이 클래스에서는 Product의 인스턴스를 생성하는 팩토리 메서드를 구현한다.

이러한 팩토리 메서드는, 객체 생성에 대한 책임을 하위 클래스로 미루어서 유연성을 제공한다. 하위 수준 모듈을 확장하고자 할 때 매우 유용하다.

다음은, 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"
profile
Back-end Developer, DevOps Engineer

0개의 댓글