Programming Languange/디자인 패턴

디자인 패턴 (Design Patterns) - Object Pool

타자치는 문돌이 2024. 4. 15. 17:57

Object Pool은 객체가 자주 생성/삭제되는 경우 그 비용을 줄이기 위한 디자인 패턴이다.
생성한 객체를 삭제하는 대신, Object Pool이란 곳에 임시로 보관하고 있다가, 새 객체가 필요할 때 객체를 생성하는 대신, Object Pool에서 객체를 꺼내 재활용하는 방식이다. GoF의 디자인 패턴에는 없는 내용이지만 자주 사용할 수 있을 것 같아 넣었다.

구현

Object

아래와 같은 객체가 있다고 하자.

// 예시 Object
class Object
{
private:
    int value;
}

Object Pool

// Object Pool
template <typename T>
class ObjectPool 
{
private:
    std::vector*> pool; // 객체들을 보관하는 벡터
    int poolSize;         // 최대 풀의 크기

public:
    ObjectPool(int size) : poolSize(size) {
         // 초기에 풀 크기만큼의 객체를 생성하여 풀에 추가
         for (int i = 0; i < poolSize; ++i) 
        {
            pool.push_back(new T()); // 각 객체를 초기화하여 풀에 추가
        }
    }

    // 객체를 대여하는 함수
    T* borrowObject() 
    {
        if (!pool.empty()) 
         {
            T* obj = pool.back(); // 풀의 마지막 객체를 대여
            pool.pop_back();      // 대여한 객체를 풀에서 제거
            return obj;
        } else {
            poolSize++
            return new T();       // 객체가 없으면 생성해서 반환
        }
    }

    // 객체를 반환하는 함수
    void returnObject(T* obj) 
    {
        if (pool.size() < poolSize) 
        {
            pool.push_back(obj); // 반환된 객체를 풀에 추가
        } else {
            // 풀이 가득 찬 경우 삭제
            delete obj;
        }
    }

    // 소멸자: 풀에 있는 모든 객체를 삭제
    ~ObjectPool() 
    {
        for (T* obj : pool) 
        {
            delete obj;
        }
    }
};

예시

int main()
{
    ObjectPool> pool(5);

    // 객체 대여 및 반환 테스트
    for (int i = 0; i < 6; ++i) {
        MyObject* obj = pool.borrowObject();
        std::cout << "Object borrowed: " << obj->getValue() << std::endl;
        obj->setValue(i); // 객체의 값을 설정
        pool.returnObject(obj);
        std::cout << "Object returned: " << obj->getValue() << std::endl;
    }

    return 0;
}

장점

  • 생성과 소멸 비용이 줄어들어 비용을 줄일 수 있다.
  • 자원이 제한된 환경에서 리소스를 효율적으로 관리할 수 있다.

단점

  • 메모리 사용량은 증가한다.
  • 멀티 스레드 환경에서는 객체의 대여와 반납이 동시에 이루어진다면 동기화가 필요하다.

 

디자인 패턴 (Design Patterns) - Index