티스토리 뷰

개발/C++

디자인 패턴에 대해 알아보자 - 프로토타입 패턴

부캐: 개발하는 조대리 2024. 10. 7. 03:02
반응형

디자인 패턴 - 프로토타입 패턴

 

 

 

 

 

 샘플 소스코드 다운로드

prototype_sample.cpp
0.00MB

 

 

 

 C++ 샘플 소스코드

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

// 프로토타입 기본 클래스
class Prototype {
public:
    virtual ~Prototype() = default;
    virtual std::unique_ptr<Prototype> clone() const = 0;
    virtual void print() const = 0;
};

// 구체적인 프로토타입 클래스
class ConcretePrototype : public Prototype {
public:
    ConcretePrototype(std::string type) : type_(std::move(type)) {}
    
    // 복사 생성자
    ConcretePrototype(const ConcretePrototype& other) : type_(other.type_) {}

    std::unique_ptr<Prototype> clone() const override {
        return std::make_unique<ConcretePrototype>(*this);
    }

    void print() const override {
        std::cout << "Type: " << type_ << std::endl;
    }

private:
    std::string type_;
};

// 프로토타입 관리자 클래스
class PrototypeManager {
public:
    void addPrototype(const std::string& key, std::unique_ptr<Prototype> prototype) {
        prototypes_[key] = std::move(prototype);
    }

    std::unique_ptr<Prototype> getPrototype(const std::string& key) {
        auto it = prototypes_.find(key);
        if (it != prototypes_.end()) {
            return it->second->clone();
        }
        return nullptr;
    }

private:
    std::unordered_map<std::string, std::unique_ptr<Prototype>> prototypes_;
};

int main() {
    PrototypeManager manager;

    manager.addPrototype("type1", std::make_unique<ConcretePrototype>("Type1"));
    manager.addPrototype("type2", std::make_unique<ConcretePrototype>("Type2"));

    auto clonedType1 = manager.getPrototype("type1");
    if (clonedType1) {
        clonedType1->print();
    }

    auto clonedType2 = manager.getPrototype("type2");
    if (clonedType2) {
        clonedType2->print();
    }

    return 0;
}

 

 

 

 구현에 대한 설명

  1. 가상 소멸자: Prototype 기본 클래스에 가상 소멸자를 사용하여 다형성을 올바르게 지원합니다.
  2. 순수 가상 함수: clone()과 print() 함수를 순수 가상 함수로 선언하여 인터페이스를 정의합니다.
  3. 복사 생성자: ConcretePrototype 클래스에 명시적인 복사 생성자를 정의하여 깊은 복사를 보장합니다.
  4. 스마트 포인터: std::unique_ptr를 사용하여 메모리 관리를 자동화합니다.
  5. 이동 의미론: PrototypeManager::addPrototype 함수에서 std::move를 사용하여 불필요한 복사를 방지합니다.
  6. 예외 안전성: 포인터 대신 스마트 포인터를 사용하여 예외 발생 시에도 메모리 누수를 방지합니다.

 

 

 

 이 구현 방식의 장점

  • 새로운 객체 생성 시 서브클래싱 대신 복제를 사용하여 유연성을 제공합니다.
  • 런타임에 객체 추가와 삭제가 가능합니다.
  • 복잡한 객체의 생성 과정을 단순화할 수 있습니다.

 

 

 

 주의할 점

  • 순환 참조가 있는 복잡한 객체의 경우 클론 생성이 어려울 수 있습니다.
  • 깊은 복사를 구현해야 하는 경우 복잡도가 증가할 수 있습니다.

 

 

 


 

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

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