2. 빌더 패턴(Builder Pattern) 구현

빌더 패턴 프로젝트 다운로드

2. 4 구현

이제 빌더 패턴에 대한 예제 프로그램을 구현해 봅시다. 구현 순서는 사진, 사진 빌더, 카메라 순으로 하겠습니다.

2.4.1 사진

사진은 피사체와 이에 대한 이미지를 갖는 형식으로 정의를 할게요.

▶Picture.cs

namespace Builder
{
    class Picture
    {
        public static readonly Picture EmptyPicture;
        static Picture()
        {
            EmptyPicture = new Picture(string.Empty, string.Empty);
        }
        public string Subject
        {
            get;
            private set;
        }
        public string Image
        {
            get;
            private set;
        }
        public Picture(string subject, string image)
        {
            Subject = subject;
            Image = image;
        }
    }
}

2.4.2 사진 빌더

사진 빌더는 빛을 모아 피사체를 이미지로 맺히는 역할과 수정작업을 수행하는 역할을 합니다. 추상 클래스 PictureBuilder에는 이들 기능에 대한 약속을 합니다.

▶PictureBuilder.cs

namespace Builder
{
    abstract class PictureBuilder
    {
        public Picture Picture
        {
            get;
            protected set;
        }
        public abstract void SetSubject(string subject); //상을 맺히는 기능
        public abstract void Change();//이미지를 수정하는 기능
    }
}

SmoothBuilder에서는 약속한 기능을 구체적으로 구현해야 합니다. 상을 맺히는 기능은 피사체를 그대로 이미지로 맺히게 구현할게요. 그리고 이미지를 수정하는 기능은 날카로운 부분을 부드럽게 바꾸게 구현합시다.

▶SmoothBuilder.cs

namespace Builder
{
    class SmoothBuilder:PictureBuilder
    {
        const string sharp = "Sharp";
        const string smooth = "Smooth";
        string subject;  //원본 피사체
        public override void SetSubject(string subject) //상을 맺히는 기능
        {
            this.subject = subject;
            Picture = new Picture(subject, subject);
        }
        public override void Change()//이미지를 수정하는 기능
        {
            string image = subject.Replace(sharp,smooth);
            Picture= new Picture(subject,image);
        }
    }
}

REPreventBuilder에서도 약속한 기능을 구체적으로 구현해야 합니다. 상을 맺히는 기능은 피사체의 일부분만 이미지로 맺히게 구현할게요. 그리고 이미지를 수정하는 기능은 적목을 일반적인 눈으로 바꾸게 구현합시다.

▶REPreventBuilder.cs

namespace Builder
{
    class REPreventBuilder:PictureBuilder
    {
        const string red_eye = "RedEye";
        const string normal_eye = "NomalEye";
        const int max_length = 20;
        string subject;

        public override void SetSubject(string subject) //상을 맺히는 기능
        {
            if (subject.Length > max_length)
            {
                subject = subject.Substring(0, max_length);
            }
            this.subject = subject;
        }
        
        public override void Change()//이미지를 바꾸는 기능
        {
            string image = subject.Replace(red_eye, normal_eye);
            Picture = new Picture(subject, image);
        }
    }
}

2.4.3 카메라

카메라에는 셔터를 누르면 피사체를 사진으로 만들어주는 기능이 있어야 할 것입니다. 이러한 기능을 PressAShutter라 하고 피사체와 낮인지 밤인지를 구별할 수 있는 입력 인자로 받아서 빌더를 이용하여 상을 맺히고 수정하게 구현할게요.

▶Camera.cs

namespace Builder
{
    class Camera
    {
        PictureBuilder[] builders = new PictureBuilder[2];
        public Picture MyPicture
        {
            get;
            private set;
        }
        public Camera()
        {
            builders[0] = new REPreventBuilder();
            builders[1] = new SmoothBuilder();
            MyPicture = Picture.EmptyPicture;
        }
        public void PressAShutter(string origin,bool night)
        {
            PictureBuilder pb = null;
            if (night) //밤일 때
            {
                pb = builders[0];
            } 
            else//밤이 아닐 때
            {
                pb = builders[1];
            } 

            pb.SetSubject(origin); //상을 맺힌다.
            pb.Change(); //이미지를 수정한다.
            MyPicture = pb.Picture;
        }
    }
}

▶Program.cs

using System;
namespace Builder
{
    class Program
    {
        static void Main(string[] args)
        {
            Camera camera = new Camera();
            camera.PressAShutter("길 마당 RedEyeSharpBody 집 산 ",true);
            Console.WriteLine(camera.MyPicture.Image);
            camera.PressAShutter("길 마당 RedEyeSharpBody 집 산",false);
            Console.WriteLine(camera.MyPicture.Image);
        }
    }
}

▶실행 결과

길 마당 NomalEyeSharpBody
길 마당 RedEyeSmoothBody 집 산