본문 바로가기

Design Pattern

[Design Pattern] 15. Flyweight Pattern(플라이웨이트 패턴) C#

728x90

공통된 속성을 가진 객체를 공유해 줘 RAM(리소스)를 절약할 수 있도록 도와주는 패턴입니다

 

구조 패턴(Structural Design Patterns)중 하나이죠.

 

장점

  • 유사한 객체가 많을 경우 많은 RAM을 절약할 수 있습니다.

단점

  • 코드가 복잡해지며 타인이 코드를 볼 때 개체의 상태가 왜 그런 식으로 분리되었나 이해하지 못할 수 있습니다.
  • 플라이웨이트 메서드를 호출할 때마다 콘텍스트 데이터를 계산해야 한다면 RAM을 덜 사용하는 대신 CPU에 부담을 주고있을 가능성이 있습니다.

 

C#으로 Console 프로젝트를 하나 생성해서 할 것입니다.

 

목표는 로봇을 생산하고 Print를 통한 로봇의 이름 조회를 해보겠습니다.

 

프로젝트의 tree구조는 아래와 같습니다.

Flyweight (Project)

|- Program.cs (Main)

|- IRobot.cs (Flyweight interface)

|- Robot.cs (Concrete Flyweight class)

|- RobotFactory.cs (Flyweight factory)

 

IRobot.cs

namespace Flyweight
{
    public interface IRobot
    {
        void Print();
    }
}

Print를 구성해서 IRobot에서 사용할 수 있게 만듭니다.


Robot.cs

using System;

namespace Flyweight
{
    public class Robot : IRobot
    {
        private string name;

        public Robot(string name)
        {
            this.name = name;
        }

        public void Print()
        {
            Console.WriteLine($"name: {name}");
        }
    }
}

IRobot을 구현해서 name을 출력하게 만들어 줍니다.


RobotFactory.cs

using System.Collections.Generic;

namespace Flyweight
{
    public class RobotFactory
    {
        private Dictionary<string, IRobot> robots = new Dictionary<string, IRobot>();

        public IRobot GetRobot(string name)
        {
            if (!robots.ContainsKey(name))
            {
                robots[name] = new Robot(name);
            }
            return robots[name];
        }

        public int Count()
        {
            return robots.Count;
        }
    }
}

Robot객체를 생성하고 만약 같은 이름을 공유할 경우 이전에 생성한 Robot을 리턴해줍니다.

Dictionary타입을 통해 이름으로 데이터를 조회하고 만약 해당 이름이 없을 경우 새로 생성해줍니다.


Program.cs

using System;

namespace Flyweight
{
    class Program
    {
        static void Main(string[] args)
        {
            RobotFactory factory = new RobotFactory();

            IRobot robot1 = factory.GetRobot("Robot 1");
            robot1.Print();

            IRobot robot2 = factory.GetRobot("Robot 2");    
            robot2.Print();

            IRobot robot3 = factory.GetRobot("Robot 1");
            robot3.Print();

            Console.WriteLine("Number of robots created: " + factory.Count());
        }
    }
}

factory를 하나 만들고 Robot 1이라는 개체를 가져와 출력 Robot 2도 동일하게 해준 뒤 robot3의 경우 Robot 1이라는 이름으로 가져와 Print해줍니다.

원하는대로 Robot 1으로 출력되며 지금까지 생성된 로봇의 갯수를 출력하면 2로 robot3의 경우 robot1과 같은 개체를 쓰고있음을 알 수 있습니다.

 

실행 결과

 

RAM 대신에 CPU를 쓰는 느낌이라 자주 사용되진 않는거 같습니다.