STUDY/Design Pattern

경량 패턴(Flyweight Pattern)

디리릭 2022. 12. 19. 01:58
728x90

공유 풀(메모리 풀) 미리 형성하여 참조하는 개체를 처음에 사용할 때 저장한 뒤, 그 이후에 사용할 때에는 저장해 둔 데이터를 사용하여 메모리 절약하는 패턴이다. 이 패턴은 많은 수의 객체를 생성할 때 주로 쓰인다.

대표적인 예로는, 게임에서 숲이나 유닛, 지형 등 환경 오브젝트와 같이 서로 비슷한 요소를 가지면서 많은 객체를 필요로 할 때 사용된다.

메모리 풀은 일정 갯수의 데이터 공간을 정해두고, 그 공간만큼 사용할 데이터를 저장하여 사용한다. 메모리 풀이 가득차게 되면 지정해 둔 알고리즘을 통해 데이터를 삭제하고 추가하거나 참조만으로 사용한다.

구조

▷FlyweightFactory: 공유 객체 풀을 관리하는 팩토리 클래스

▷Flyweight: 공유 객체에 대한 구현 클래스

시나리오

내가 좋아하는 헤이데이 모바일 게임에서는 작물을 심고 수확을 할 수 있다.

수확한 작물로는 케이크, 아이스크림, 주스 등등으로 상품을 만들 수 있다.

flyweight패턴 사용하여 수많은 작물을 심고 수확하는 것을 나타내려고 한다.

구현

 public interface IHayday
    {
        void Operation();
    }
  public class Wheat : IHayday
    {
        public void Operation()
        {
            Console.WriteLine("PLANTING WHEAT (" + GetHashCode() + ")");
        }
    }
 public class Bean : IHayday
    {
        public void Operation()
        {
            Console.WriteLine("PLANTING BEAN (" + GetHashCode() + ")");
        }
    }
  public class Chili : IHayday
    {
        public void Operation()
        {
            Console.WriteLine("PLANTING CHILI (" + GetHashCode() + ")");
        }
    }
    public class HaydayFactory
    {
        private Dictionary<string, IHayday> _haydayweights;
        public HaydayFactory() 
        {
            _haydayweights = new Dictionary<string, IHayday>();
        }

        public IHayday GetHaydayweight(string key) 
        {
            IHayday haydayweight;
            _haydayweights.TryGetValue(key, out haydayweight);
            if (haydayweight == null) 
            {
                switch (key.ToUpper()) 
                {
                    case "WHEAT":
                        haydayweight = new Wheat();
                        break;
                    case "BEAN":
                        haydayweight = new Bean();
                        break;
                    case "CHILI":
                        haydayweight = new Chili();
                        break;
                }
                _haydayweights.Add(key, haydayweight);
                //Type type = Assembly.GetExecutingAssembly().GetType(key);
                //object instance = Activator.CreateInstance(type);
                //MethodInfo method = type.GetMethod("");
                //haydayweight = method.Invoke(instance, new object[0]);
            }

            return haydayweight;
        }
    }
       static void Main(string[] args)
        {
            HaydayFactory flyweightFactory = new HaydayFactory();

            IHayday[] flyweights = new IHayday[]
            {
            flyweightFactory.GetHaydayweight("wheat"),
            flyweightFactory.GetHaydayweight("wheat"),
            flyweightFactory.GetHaydayweight("bean"),
            flyweightFactory.GetHaydayweight("chili"),
            flyweightFactory.GetHaydayweight("chili")
            };

            foreach (IHayday flyweight in flyweights)
            {
                flyweight.Operation();
            }
            Console.Read();
        }

RESULT >>>>

이 패턴의 장점은 공통적인 속성을 갖는 많은 객체를 생성할 때 메모리를 아낄 수 있다는 점이다.

단점은 데이터를 서로 공유하여 사용하도록 구현되었기 때문에 해당 패턴에 포함 된 객체들 중에서 일부만 다른 방식으로 구현하기는 어렵다는 점이다.

H/W)

WPF or winform

버튼 1개 -> 랜덤함수를 사용해서 경우의 수가 2개 (글씨색이 빨강 또는 파랑)

버튼을 생성할떄 글씨색이 정햏짐

이러한 버튼을 10개가 화면에 보이도록 구현

버튼 -> 나무 하나

버튼의 조건!

글씨색이 빨강색인데, 검정-> 빨강 무한히 깜빡

=> 완벽한 flyweight를 구현하기는 힘들다.

버튼을 생성하는것만 봐도 버튼 10개를 생성해야하므로 flyweight의 이점을 살릴 수가 없다.

728x90