Design Pattern

[Design Pattern] 16. Proxy Pattern(프록시 패턴) C#

o0zrone 2023. 4. 5. 20:26
728x90

실제 개체와 사용자 사이에서 중개자와 같이 존재하고 실제 개체에 캐싱, 로깅같은 추가 기능을 사용할 수 있도록 도와주는 패턴입니다

 

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

 

장점

  • 서비스 객체가 로딩되지 않은 상태에서 서비스 객체를 제어할 수 있습니다.
  • 개방/폐쇄 원칙을 만족하여 코드를 변경하지 않고도 새 프록시들을 도입할 수 있습니다.
  • 신경 쓰지 않을 때 서비스 객체의 수명 주기를 관리할 수 있습니다.

단점

  • 클래스가 많아져 코드가 복잡해질 수 있습니다.
  • 프로그램의 응답이 늦어질 수 있습니다

 

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

 

목표는 이미지를 디스플레이 해보겠습니다.

 

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

Proxy (Project)

|- Program.cs (Main)

|- IImage.cs (Subject interface)

|- RealImage.cs (Real Subject class)

|- ImageProxy.cs (Proxy class)

 

IImage.cs 

namespace proxy
{
    public interface IImage
    {
        void Display();
    }

}

Display를 통해 띄울수 있게 구성해줍니다.

 

 

RealImage.cs

using System;

namespace proxy
{
    public class RealImage : IImage
    {
        private string _fileName;

        public RealImage(string fileName)
        {
            _fileName = fileName;
            LoadImageFromDisk();
        }

        public void Display()
        {
            Console.WriteLine("Displaying image: " + _fileName);
        }

        private void LoadImageFromDisk()
        {
            Console.WriteLine("Loading image from disk: " + _fileName);
        }
    }
}

IImage를 구현해주며 실제 파일에 엑세스해서 Load해주는 LoadImageFromDisk()를 추가롤 만들어 줍니다.

예제에서는 Console출력으로 대체하겠습니다.

 

ImageProxy.cs

namespace proxy
{
    public class ImageProxy : IImage
    {
        private RealImage _realImage;
        private string _fileName;

        public ImageProxy(string fileName)
        {
            _fileName = fileName;
        }

        public void Display()
        {
            if (_realImage == null)
            {
                _realImage = new RealImage(_fileName);
            }
            _realImage.Display();
        }
    }
}

프록시 클래스를 만들어줘서 Real Image가 로드가 다되어있으면 Display를 시키고 그렇지 않으면 새로 만들어 Display하게 만들어 줍니다.

 

 Program.cs

namespace proxy
{
    class Program
    {
        static void Main(string[] args)
        {
            IImage image = new ImageProxy("test.jpg");
            image.Display();
        }   
    }
}

프록시 개체를 만들어 Display해줍니다.

따로 RealImage를 만들거나 하지않았기 때문에 프록시에서 RealImage를 만들고 받아서 Display해줍니다.

아래와 같이 원하는 출력이 나왔음을 확인할 수 있습니다.

실행 결과

 

여러모로 가독성이나 알기쉬운 코드가 좋기 때문에 별로 사용해 본 경험이 없는 패턴인거 같습니다.

그래도 때로 개체 접근에 캐싱하고 로깅하거나 추가적으로 보안을 위해 사용할 수 있으니 알아두는게 좋을 것 같습니다.