4. 원형 패턴(Prototype Pattern) 구현

원형 패턴 프로젝트 파일 다운로드

4. 4 구현

이제 원형 패턴에 대한 예제 프로그램을 구현해 봅시다. 구현 순서는 줌 렌즈, 줌 렌즈 생산 라인, 렌즈 공장과 테스트 코드 순서로 구현할게요.

4.4.1 줌 렌즈

여기에서는 원형 패턴을 사용할 것이므로 다양한 줌 렌즈를 일반화 관계를 사용하지 않고 하나의 ZoomLens 클래스에서 속성만 다르게 주고 자신을 복사하는 메서드를 제공하기로 할게요. 이에 줌 렌즈의 생성자에서는 줌 레벨의 최소값과 최대값, 초점 거리의 최소값과 최대값을 인자로 전달받아 생성하도록 할게요. 원형 패턴을 사용하지 않고 일반화 관계를 사용한다면 많으 수의 파생 클래스가 필요할 것입니다.

C#에서는 이와 같이 자신을 복제 가능한 형식들을 위해 IConeable 인터페이스가 정의되어 있습니다. 여기에서도 ZoomLens는 ICloneable 인터페이스를 기반으로 정의할게요. 그리고 줌 인, 줌 아웃, 초점을 가까운 곳으로 이동, 먼 곳으로 이동시키는 기능과 피사체를 사진으로 변환하는 기능을 추가합시다.

▶ZoomLens.cs

using System;
namespace Prototype
{
    class ZoomLens:ICloneable //복제 가능한 클래스
    {
        readonly int min_zoomlevel;
        readonly int max_zoomlevel;
        int zoomlevel;
        readonly int min_focus;
        readonly int max_focus;
        int focus;

        public ZoomLens(int min_zlevel, int max_zlevel, int min_focus, int max_focus)
        {
            this.min_zoomlevel=min_zlevel;
            this.max_zoomlevel=max_zlevel;
            this.min_focus=min_focus;
            this.max_focus=max_focus;
            zoomlevel = min_zlevel;
            focus = min_focus;
        }

        public void Take()
        {
            Console.WriteLine("줌 레벨 가능 범위:{0}~{1}", min_zoomlevel,max_zoomlevel);
            Console.WriteLine("현재 줌레벨:{0}",zoomlevel);
            Console.WriteLine("포커스 조절 범위:{0}~{1}",min_focus,max_focus);
            Console.WriteLine("현재 포커스:{0}",focus);
        }

        public int ZoomIn()
        {
            if(zoomlevel<max_zoomlevel)
            {
                zoomlevel++;
            }
            return zoomlevel;
        }

        public int ZoomOut()
        {
            if(zoomlevel>min_zoomlevel)
            {
                zoomlevel--;
            }
            return zoomlevel;
        }

        public int NearFocus()
        {
            if(focus>min_focus)
            {
                 focus--;
            }
            return focus;
        }
        public int FarFocus()
        {
            if(focus<max_focus)
            {
                focus++;
            }
            return focus;
        }

        public object Clone()//자신을 복제한 개체를 반환하는 메서드
        {
            return new ZoomLens(min_zoomlevel, max_zoomlevel, min_focus, max_focus);
        }
    }
}


4.4.2
줌 렌즈 생산 라인

생산 설비는 하나의 줌 렌즈를 모형으로 갖고 있고 이를 기반으로 복사된 렌즈를 생산하기로 하였습니다. 이를 위해 생산 설비의 생성자는 어떠한 모형 렌즈를 갖고 있을 것인지를 입력 인자로 전달받기로 하겠습니다. 그리고 렌즈 생산 요청을 받아 복제된 제품을 생산하는 메서드를 MakeLens라 하겠습니다.

▶ProLine.cs

namespace Prototype
{
    enum TypeZoomLens{    NM_NM,  NM_NF,  NF_NF,  MF_NF,  MF_MF  }
    class ProLine
    {
        ZoomLens pt = null;
        public ProLine(TypeZoomLens typezoomlens)
        {
            switch (typezoomlens)
            {
            case TypeZoomLens.NM_NM: pt = new ZoomLens(20, 70, 1, 100); break;
            case TypeZoomLens.NM_NF: pt = new ZoomLens(20, 70, 1, 200); break;
            case TypeZoomLens.NF_NF: pt = new ZoomLens(20, 300, 1, 200); break;
            case TypeZoomLens.MF_NF: pt = new ZoomLens(70, 300, 1, 200); break;
            case TypeZoomLens.MF_MF: pt = new ZoomLens(70, 300, 10, 200); break;
            default: pt = new ZoomLens(20, 70, 1, 100); break;
            }
        }
        public ZoomLens MakeLens() // 주문한 렌즈를 복제하여 생산하는 메서드
        {
            return pt.Clone() as ZoomLens;
        }
    }
}


4.4.3
렌즈 공장과 테스트 코드

렌즈 공장에서는 여러 종류의 생산 설비들로 구성되어 있고 클라이언트로부터 렌즈를 만들어 제공하는 메서드가 필요하겠죠.

▶LensFactory.cs

using System.Collections.Generic;
namespace Prototype
{
    class LensFactory
    {
        List<ProLine> lines = new List<ProLine>();
        public int GetMaxLines()
        {
            return lines.Count;
        }
        public LensFactory()
        {
            lines.Add(new ProLine( TypeZoomLens.NM_NM));
            lines.Add(new ProLine( TypeZoomLens.NM_NF));
            lines.Add(new ProLine( TypeZoomLens.NF_NF));
            lines.Add(new ProLine( TypeZoomLens.MF_NF));
            lines.Add(new ProLine(TypeZoomLens.MF_MF));
        }
        public ZoomLens Order(int index) //소비자가 주문한 렌즈를 생산
        {
            if ((index >= 0) && (index < lines.Count))
            {
                ProLine pline = lines[index];
                return pline.MakeLens();
            }
            return null;
        }
    }
}

테스트 코드에서는 공장을 통해 여러 종류의 렌즈 정보를 확인하는 것으로 하겠습니다.

▶Program.cs

using System;
namespace Prototype
{
    class Program
    {
        static void Main(string[] args)
        {
            LensFactory factory = new LensFactory();
            int lcnt = factory.GetMaxLines();
            ZoomLens lens = null;

            for(int i = 0; i<lcnt; i++)
            {
                lens = factory.Order(i);
                if(   lens != null )
                {
                    lens.Take();
                    Console.WriteLine();
                }
            }
        }
    }
}

▶실행 결과

줌 레벨 가능 범위:20~70
현재 줌레벨:20
포커스 조절 범위:1~100
현재 포커스:1

줌 레벨 가능 범위:20~70
현재 줌레벨:20
포커스 조절 범위:1~100
현재 포커스:1

줌 레벨 가능 범위:20~70
현재 줌레벨:20
포커스 조절 범위:1~100
현재 포커스:1

줌 레벨 가능 범위:20~70
현재 줌레벨:20
포커스 조절 범위:1~100
현재 포커스:1

줌 레벨 가능 범위:20~70
현재 줌레벨:20
포커스 조절 범위:1~100
현재 포커스:1