2 minute read

팩토리(Factory) 패턴이란?


팩토리 패턴은 객체 생성을 위한 인터페이스를 정의하고, 어떤 클래스의 인스턴스를 생성할지는 서브클래스에서 결정하도록 하는 디자인 패턴입니다.
즉, 객체 생성 로직을 캡슐화하여 클라이언트 코드에서 구체 클래스에 대한 의존성을 제거합니다.



팩토리(Factory)의 종류


  • 단순 팩토리 (Simple Factory): 객체 생성을 담당하는 하나의 클래스를 사용합니다. 팩토리 클래스 내부에 조건문을 사용하여 어떤 객체를 생성할지 결정합니다.
  • 팩토리 메서드 (Factory Method): 객체 생성을 위한 인터페이스를 정의하고, 구체적인 객체 생성은 서브클래스에서 담당하도록 합니다.
  • 추상 팩토리 (Abstract Factory): 관련 있는 객체들을 생성하기 위한 인터페이스를 제공하며, 구체적인 팩토리를 통해 객체를 생성합니다.

팩토리(Factory) 패턴의 장단점


장점

  • 객체 생성 로직 캡슐화: 객체 생성 로직을 팩토리 클래스에 캡슐화하여 클라이언트 코드에서 구체 클래스에 대한 의존성을 제거합니다.
  • 유연성 향상: 새로운 객체 타입을 추가하더라도 기존 코드를 수정할 필요가 없습니다. 새로운 팩토리 클래스를 추가하면 됩니다.
  • 코드 재사용성 향상: 객체 생성 로직을 재사용할 수 있습니다.
  • OCP (Open/Closed Principle) 준수: 확장에 대해서는 열려 있고, 변경에 대해서는 닫혀 있는 객체지향 디자인 원칙을 준수합니다.

단점

  • 클래스 증가: 팩토리 클래스를 추가해야 하므로, 클래스 수가 증가할 수 있습니다. (특히 팩토리 메서드, 추상 팩토리)
  • 복잡성 증가: 객체 생성 로직이 복잡한 경우, 팩토리 패턴을 적용하면 코드의 복잡성이 증가할 수 있습니다.

구현


[단순 팩토리]

#include <iostream>
#include <string>

class Product { // 제품 인터페이스
public:
    virtual ~Product() {}
    virtual void use() = 0;
};

class ConcreteProductA : public Product { // 구체적인 제품 A
public:
    void use() override {
        std::cout << "Using ConcreteProductA" << std::endl;
    }
};

class ConcreteProductB : public Product { // 구체적인 제품 B
public:
    void use() override {
        std::cout << "Using ConcreteProductB" << std::endl;
    }
};

class SimpleFactory { // 단순 팩토리
public:
    static Product* createProduct(char type) {
        if (type == 'A') {
            return new ConcreteProductA();
        } else if (type == 'B') {
            return new ConcreteProductB();
        } else {
            return nullptr; // 잘못된 타입
        }
    }
};

int main() {
    Product* productA = SimpleFactory::createProduct('A');
    if (productA != nullptr) {
        productA->use(); // Using ConcreteProductA
        delete productA;
    }

    Product* productB = SimpleFactory::createProduct('B');
    if (productB != nullptr) {
        productB->use(); // Using ConcreteProductB
        delete productB;
    }

    Product* productC = SimpleFactory::createProduct('C'); // 잘못된 타입
    if (productC == nullptr){
        std::cout << "Invalid product type" << std::endl;
    }

    return 0;
}


[팩토리 메서드 (Factory Method)] 팩토리 메서드 패턴은 객체 생성을 위한 인터페이스를 정의하고, 구체적인 객체 생성은 서브클래스에서 담당하도록 합니다.

#include <iostream>
#include <string>

class Product { // 제품 인터페이스
public:
    virtual ~Product() {}
    virtual void use() = 0;
};

class ConcreteProductA : public Product { // 구체적인 제품 A
public:
    void use() override {
        std::cout << "Using ConcreteProductA" << std::endl;
    }
};

class ConcreteProductB : public Product { // 구체적인 제품 B
public:
    void use() override {
        std::cout << "Using ConcreteProductB" << std::endl;
    }
};

class Creator { // 생성자 인터페이스
public:
    virtual ~Creator() {}
    virtual Product* createProduct() = 0;
    void someOperation() {
        Product* product = this->createProduct();
        product->use();
        delete product;
    }
};

class ConcreteCreatorA : public Creator { // 구체적인 생성자 A
public:
    Product* createProduct() override {
        return new ConcreteProductA();
    }
};

class ConcreteCreatorB : public Creator { // 구체적인 생성자 B
public:
    Product* createProduct() override {
        return new ConcreteProductB();
    }
};

int main() {
    Creator* creatorA = new ConcreteCreatorA();
    creatorA->someOperation(); // Using ConcreteProductA
    delete creatorA;

    Creator* creatorB = new ConcreteCreatorB();
    creatorB->someOperation(); // Using ConcreteProductB
    delete creatorB;

    return 0;
}



Top