C# 이것저것/C# 디자인패턴

[C#] Object Pool 패턴

agingcurve 2024. 3. 31. 15:01
반응형

Object Pool 패턴

 

카테고리 : 생성패턴 

개요 : 어떤 객체는 생성 시, 오랜시간이 걸리기도 하며, 그 일 자체가 성능에 영향을 미칠 수 있다.

이런 경우, 재사용한 가능한 객체들을 Object Pool 에 넣어 두고 클라이언트가 객체들을 다시 사용하도록 하는 것을 Object Pool 디자인 패턴이라 한다.

 

사용할 객체를 그때 그때 생성하고 소멸하는 것이 아니라, Pool에 객체를 저장해두고 이를 꺼내서 사용하는 방식이다.

클라이언트로 부터 객체 요청이 오면, Pool에 사용 가능한 객체가 있는지 보고, 재사용 가능한 객체가 있다면 객체를 리턴하고, 만약 없으면 새로 객체를 생성하여 리턴한다. 

클라이언트가 객체 사용을 끝내면, 객체를 소멸시키지 않고, 그 객체를 다시 Pool에 리턴하게 된다.

 

Object Pool 패턴을 구현하기 위해선, 먼저 재사용하고하는 객체 클래스, Object 클래스를 정의하고, 이 재사용 가능한 객체들의 Pool을 관리하기 위한 Object Pool 클래스를 정의한다.

Object Pool 클래스의 GetObject 메서드를 호출하여 Pool에서 객체를 가져와 사용하고, 사용이 끝나면 Release Object 메서드를 호출해 객체를 다시 Pool로 돌려보낸다.

 

아래 코드는 Connection Pooling을 시뮬레이션 한것으로, MyConnectionPool.GetObject() 메서드를 통해 재사용 가능 한 Connection 객체를 가져오고, MyConnectionPool.RealseObject() 메서드를 통해 사용 마친 Connection을 Pool에 돌려줌

 

using System.Collections.Concurrent;
using System.Diagnostics;

namespace Object_Pool
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Client.HowToUse();
        }

        // Reusable Object 클래스
        public class MyConnection
        {
            public MyConnection()
            {

            }
        }

        public class MyConnectionPool
        {
            //Thread-safe 컬렉션
            private readonly ConcurrentBag<MyConnection> pool = new ConcurrentBag<MyConnection>();

            public MyConnection GetObject()
            {
                MyConnection obj;
                if(pool.TryTake(out obj))
                {
                    // 기존객체 리턴
                    return obj;
                }
                else
                {
                    return new MyConnection();
                }

            }

            public void RealeaseObject(MyConnection conn)
            {
                //Release 하면 Pool에 추가
                pool.Add(conn);
                Console.WriteLine($"Realse : {conn.GetHashCode()}");
            }
        }

        /* 클라이언트 */
        class Client
        { 
            public static void HowToUse()
            {
                var myPool = new MyConnectionPool();
                MyConnection conn = myPool.GetObject();
                // MyConnection 객체 사용
                myPool.RealeaseObject(conn);
                MyConnection conn2 = myPool.GetObject();
                // MyConnection 객체 사용..
                myPool.RealeaseObject(conn2);
            }
        }


    }
}

'C# 이것저것 > C# 디자인패턴' 카테고리의 다른 글

[C#] Proxy 패턴  (0) 2024.04.15
[C#] Decorator 패턴  (0) 2024.04.15
[C#] Bridge 패턴  (0) 2024.04.06
[C#] Adapter 패턴  (0) 2024.03.31