[디자인패턴] 팩토리 패턴[Factory Pattern](C#)

팩토리 패턴 - 객체를 생성하기 위한 인터페이스를 만듭니다.

어떤 클래스의 인스턴스를 만들지는 서브 클래스에서 결정하도록 합니다.

팩토리 메소드를 이용하면 인스턴스를 만드는 일을 서브 클래스로 미룰 수 있습니다.


팩토리 패턴의 핵심정리


○ 팩토리를 쓰면 객체 생성을 캡슐화할 수 있습니다.


○ 간단한 팩토리는 엄밀하게 말해서 디자인 패턴은 아니지만, 클라이언트와 구성 클래스를 분리

    시키기 위한 간단한 기법으로 활용 할 수 있습니다.


○ 팩토리 메소드 패턴에서는 상속을 활용합니다. 객체 생성이 서브클래스에게 위임되죠.

    서브클래스에게 위임되죠. 서브클래스에서는 팩토리 메소드를 구현하여 객체를 생산합니다.


○ 추상 팩토리 패턴에서는 객체 구성을 활용합니다.

    객체 생성이 팩토리 인터페이스에서 선언한 메소드들에서 구현되죠.


○ 모든 팩토리 패턴에서는 애플리케이션의 구상 클래스에 대한 의존성을 줄여줌으로써

    느슨한 결합을 도와줍니다.


○ 팩토리 메소드 패턴에서는 어떤 클래스에서 인스턴스를 만드는 일을 서브 클래스한테 넘깁니다.


○ 추상 팩토리 패턴은 구상 클래스에 직접 의존하지 않고도

    서로 관련된 객체들로 이루어진 제품군을 만들기 위한 용도로 쓰입니다.


○ 의존성 뒤집기 원칙을 따르면 구상 형식에 대한 의존을 피하고 추상화를 지향할 수 있습니다.


○ 팩토리는 구상 클래스가 아닌 추상 클래스/인터페이스에 맞춰서

    코딩할 수 있게 해 주는 강력한 기법입니다.


팩토리 패턴의 클래스 디자인

 

using System;
using System.Collections;
using System.Text;

namespace Factory
{
    public abstract class PizzaStore
    {
        public Pizza orderPizza(string type)
        {
            Pizza pizza;

            pizza = createPizza(type);

            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();

            return pizza;
        }

        protected abstract Pizza createPizza(string type);
    }

    public class NYPizzaStore : PizzaStore
    {
        protected override Pizza createPizza(string item)
        {
            if (item.Equals("cheese"))
            {
                return new NYStyleCheesePizza();
            }
            else
            {
                return null;
            }
        }
    }

    public class ChicagoPizzaStore : PizzaStore
    {
        protected override Pizza createPizza(string item)
        {
            if (item.Equals("cheese"))
            {
                return new ChicagoStyleCheesePizza();
            }
            else
            {
                return null;
            }
        }
    }

    public abstract class Pizza
    {
        public string name;
        public string dought;
        public string sauce;
        public ArrayList toppings = new ArrayList();

        public void prepare()
        {
            Console.WriteLine(name + "을 만들고 있습니다.");
            Console.WriteLine("도우를 던지고 있습니다...");
            Console.WriteLine("소스를 뿌리고 있습니다...");
            Console.WriteLine("토핑중입니다...");
            for (int i = 0; i < toppings.Count; i++)
            {
                Console.WriteLine("   " + toppings[i].ToString());
            }
        }

        public virtual void bake()
        {
            Console.WriteLine("350℃에 25분동안 굽습니다.");
        }

        public virtual void cut()
        {
            Console.WriteLine("피자를 대각선으로 한조각씩 자릅니다.");
        }

        public virtual void box()
        {
            Console.WriteLine("피자를 피자박스에 넣습니다.");
        }

        public string getName()
        {
            return name;
        }

    }

    public class NYStyleCheesePizza : Pizza
    {
        public NYStyleCheesePizza()
        {
            name = "마리나라 소스와 얇은 크러스트의 뉴욕풍 피자";
            dought = "얇은 크러스트 도우";
            sauce = "마리나라 소스";

            toppings.Add("잘게 썬 레지아노 치즈");
        }

        public override void box()
        {
            Console.WriteLine("특별 네모 박스에 넣습니다.");
        }
    }

    public class ChicagoStyleCheesePizza : Pizza
    {
        public ChicagoStyleCheesePizza()
        {
            name = "플럼 토마토 소스와 두꺼운 크러스트의 시카고 피자";
            dought = "아주 두꺼운 크러스트 도우";
            sauce = "플럼 토마토 소스";

            toppings.Add("조각낸 모짜렐라 치즈");
        }

        public override void cut()
        {
            Console.WriteLine("크게 자릅니다.");
        }
    }

    public class PizzaTestDrive
    {
        static void Main(string[] args)
        {
            // 우선 두 가지 피자 가게를 만듭니다.
            PizzaStore nyStore = new NYPizzaStore();
            PizzaStore chicagoStore = new ChicagoPizzaStore();
            Pizza pizza;

            // 그리고 nyStore를 써서 뉴욕풍 피자를 만듭니다.
            pizza = nyStore.orderPizza("cheese");
            Console.WriteLine("주문한 피자 " + pizza.getName() + " 나왔습니다.\n\n");
           
            pizza = chicagoStore.orderPizza("cheese");
            Console.WriteLine("주문한 피자 " + pizza.getName() + " 나왔습니다.\n\n");

        }
    }

}


위 코드에 대한 출력화면 입니다.

 
출처 : Head Firstd의 Design Patterns 책의 내용을 C#으로 만들어본 것입니다.
( 책에는 자바로만 나와있더군요 ㅠㅠ )

댓글

Designed by JB FACTORY