티스토리 뷰

개발/C++

디자인 패턴에 대해 알아보자 - 추상 팩토리 패턴

부캐: 개발하는 조대리 2024. 9. 27. 03:44
반응형

디자인 패턴 - 추상 팩토리 패턴

 

 

 

 

 

 샘플 소스코드 다운로드

abstract_factory_sample.cpp
0.00MB

 

 

 

 C++ 샘플 소스코드

#include <iostream>
#include <memory>
#include <string>

// 추상 제품 클래스들
class Chair {
public:
    virtual ~Chair() = default;
    virtual void sit() const = 0;
};

class Table {
public:
    virtual ~Table() = default;
    virtual void use() const = 0;
};

// 구체적인 제품 클래스들 - 모던 스타일
class ModernChair : public Chair {
public:
    void sit() const override {
        std::cout << "Sitting on a modern chair." << std::endl;
    }
};

class ModernTable : public Table {
public:
    void use() const override {
        std::cout << "Using a modern table." << std::endl;
    }
};

// 구체적인 제품 클래스들 - 빈티지 스타일
class VintageChair : public Chair {
public:
    void sit() const override {
        std::cout << "Sitting on a vintage chair." << std::endl;
    }
};

class VintageTable : public Table {
public:
    void use() const override {
        std::cout << "Using a vintage table." << std::endl;
    }
};

// 추상 팩토리 클래스
class FurnitureFactory {
public:
    virtual ~FurnitureFactory() = default;
    virtual std::unique_ptr<Chair> createChair() const = 0;
    virtual std::unique_ptr<Table> createTable() const = 0;
};

// 구체적인 팩토리 클래스들
class ModernFurnitureFactory : public FurnitureFactory {
public:
    std::unique_ptr<Chair> createChair() const override {
        return std::make_unique<ModernChair>();
    }
    std::unique_ptr<Table> createTable() const override {
        return std::make_unique<ModernTable>();
    }
};

class VintageFurnitureFactory : public FurnitureFactory {
public:
    std::unique_ptr<Chair> createChair() const override {
        return std::make_unique<VintageChair>();
    }
    std::unique_ptr<Table> createTable() const override {
        return std::make_unique<VintageTable>();
    }
};

// 클라이언트 코드
void clientCode(const FurnitureFactory& factory) {
    auto chair = factory.createChair();
    auto table = factory.createTable();
    
    std::cout << "Testing the furniture set:" << std::endl;
    chair->sit();
    table->use();
}

int main() {
    std::cout << "Client: Testing Modern Furniture Factory\n";
    ModernFurnitureFactory modernFactory;
    clientCode(modernFactory);
    
    std::cout << "\nClient: Testing Vintage Furniture Factory\n";
    VintageFurnitureFactory vintageFactory;
    clientCode(vintageFactory);

    return 0;
}

 

 

 

 구현에 대한 설명

  1. 추상 제품 클래스: Chair와 Table은 추상 기본 클래스로, 각 제품군의 인터페이스를 정의합니다.
  2. 구체적인 제품 클래스: ModernChair, ModernTable, VintageChair, VintageTable은 각각의 추상 제품 클래스를 구현합니다.
  3. 추상 팩토리: FurnitureFactory는 추상 팩토리 클래스로, 제품을 생성하는 인터페이스를 정의합니다.
  4. 구체적인 팩토리: ModernFurnitureFactory와 VintageFurnitureFactory는 FurnitureFactory를 구현하여 관련된 제품들을 생성합니다.
  5. 스마트 포인터 사용: std::unique_ptr을 사용하여 메모리 관리를 자동화하고 리소스 누수를 방지합니다.
  6. 개방-폐쇄 원칙: 새로운 가구 스타일을 추가할 때 기존 코드를 수정하지 않고 새로운 팩토리와 제품 클래스를 추가할 수 있습니다.
  7. 의존성 역전: 클라이언트 코드는 구체적인 클래스가 아닌 추상 인터페이스에 의존합니다.
  8. 관련 제품군: 각 팩토리는 서로 관련된 제품들(예: 모던 스타일의 의자와 테이블)을 생성합니다.

 

 

 

 이 구현 방식의 장점

  • 제품 군의 일관성을 보장합니다 (예: 모던 의자와 빈티지 테이블이 섞이지 않음).
  • 구체적인 클래스에 대한 의존성을 제거하여 결합도를 낮춥니다.
  • 새로운 변형을 쉽게 추가할 수 있어 확장성이 좋습니다.

 

 

 

 주의할 점

  • 새로운 종류의 제품을 추가하려면 모든 팩토리를 수정해야 할 수 있습니다.
  • 제품군과 변형이 많아지면 클래스 수가 급격히 증가할 수 있습니다.

 

 

 

👉 추상 팩토리 패턴은 관련된 객체들의 전체 제품군을 생성해야 할 때 특히 유용합니다. 이는 시스템이 여러 제품군 중 하나를 사용해야 하지만, 구체적인 클래스에 의존하지 않아야 할 때 이상적입니다.

 

 

 


 

개인적으로 학습하면서 정리한 내용입니다.

잘못된 내용이 있을 경우 알려주시면 확인 후 수정 및 반영하도록 하겠습니다.