본문 바로가기
CS(Computer Science)지식/[C++] 디자인 패턴

플라이급 패턴(Flyweight Pattern) 이해하기 : 쉽게 설명한 디자인 패턴(C++)

by 엔지니어 청년 2024. 1. 29.

플라이급 패턴(Flyweight Pattern)이란?


플라이급 패턴은 구조 디자인 패턴 중 하나로, 메모리 사용량을 최소화하기 위해 공유를 통해 많은 수의 비슷한 객체를 효율적으로 지원하는 것을 목표로 합니다. 이 패턴은 객체의 공유 가능한 부분(내부 상태)과 공유되지 않는 부분(외부 상태)을 분리하여, 공유 가능한 부분은 객체 간에 공유하고, 공유되지 않는 부분은 객체가 독립적으로 가지도록 합니다.

플라이급 패턴은 다음과 같은 경우에 유용합니다:

  • 많은 수의 객체를 사용해야 하고, 객체 생성 비용이 높은 경우
  • 객체의 대부분 상태가 공유 가능한 경우
  • 객체의 ID가 중요하지 않은 경우

예시 코드


다음은 C++로 작성된 간단한 플라이급 패턴의 예입니다:

#include <iostream>
#include <map>
#include <memory>

// Flyweight
class Flyweight {
public:
    virtual ~Flyweight() = default;
    virtual void operation() const = 0;
};

// Concrete Flyweight
class ConcreteFlyweight : public Flyweight {
public:
    explicit ConcreteFlyweight(int state) : state(state) {}
    void operation() const override {
        std::cout << "ConcreteFlyweight state: " << state << std::endl;
    }

private:
    int state;
};

// Flyweight Factory
class FlyweightFactory {
public:
    std::shared_ptr<Flyweight> getFlyweight(int key) {
        if (flyweights.find(key) == flyweights.end()) {
            flyweights[key] = std::make_shared<ConcreteFlyweight>(key);
        }
        return flyweights[key];
    }

private:
    std::map<int, std::shared_ptr<Flyweight>> flyweights;
};

int main() {
    FlyweightFactory factory;
    auto flyweight1 = factory.getFlyweight(1);
    flyweight1->operation();  // Output: ConcreteFlyweight state: 1

    auto flyweight2 = factory.getFlyweight(2);
    flyweight2->operation();  // Output: ConcreteFlyweight state: 2

    auto flyweight3 = factory.getFlyweight(1);
    flyweight3->operation();  // Output: ConcreteFlyweight state: 1

    return 0;
}

위 코드에서 Flyweight는 모든 플라이급이 구현해야 하는 인터페이스입니다. ConcreteFlyweightFlyweight 인터페이스를 구현하는 구체적인 플라이급입니다. FlyweightFactory는 플라이급을 생성하고 관리하는 클래스입니다. 이 팩토리는 요청받은 키에 해당하는 플라이급이 이미 존재하는 경우에는 기존의 플라이급을 반환하고, 그렇지 않은 경우에는 새로운 플라이급을 생성하여 반환합니다..

클래스 다이어그램


    +-----------------+
    |    Flyweight    |
    +-----------------+
    | virtual ~Flyweight|
    | virtual operation |
    +-----------------+
            ^
            |
    +-----------------+
    |ConcreteFlyweight|
    +-----------------+
    | operation       |
    +-----------------+
            ^
            |
    +-----------------+
    | FlyweightFactory|
    +-----------------+
    | getFlyweight    |
    +-----------------+

이 패턴을 사용하면 메모리 사용량을 크게 줄일 수 있습니다. 특히, 많은 수의 비슷한 객체를 생성해야 하는 경우에 이 패턴을 사용하면 효율적으로 객체를 관리할 수 있습니다. 하지만 이 패턴을 사용하면 코드가 복잡해질 수 있으므로, 메모리 사용량이 실제로 문제가 되는 경우에만 이 패턴을 사용하는 것이 좋습