ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [Design Pattern] 팩토리(factory) 패턴 - 디자인 패턴
    CSE/Design Pattern 2015. 6. 13. 10:24

    Pattern #1  팩토리 패턴





     생성자만으로는 개별 객체 생성이 적합하지 않은 경우 사용





     목적

      - 객체생성을 위한 인터페이스를 정의하는데 있다.

      - 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스에서 이루어지도록 인스턴스의 책임을 미룬다.



     결과

      - 다양한 형태의 객체를 반환하는 융통성을 갖게 된다.





     1. 팩토리 패턴을 사용하는 이유 


       생성자 사용할 때의 문제


        

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    Duck duck;
     
    if (picnic) {
        duck = new MallardDuck();
    else if (hunting) {
        duck = DecoyDuck();
    else if (inBathTub) {
        duck = RubberDuck();
    }
     
    cs

     


    새로운 타입이 추가될 때 문제가 된다. -> 계속해서 else if 구문을 추가해서 작성해야 함.

      





    사례 #1 - 피자 스토어


     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    Pizza orderPizza(String type) {
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("greek")) {
            pizza = new GreekPizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        }
     
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    }
     
    cs



    이와 같이 피자를 굽는 orderPizza 메소드가 있는데, 피자의 종류를 추가하거나 삭제, 변경하게 되면


    orderPizza 메소드를 바꿔줘야 한다.




    oderPizza 메소드를 다시 한 번 보면 변경, 추가, 삭제에 따른 변동이 있는 부분과 고정된 부분이 존재한다.




     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Pizza orderPizza(String type) {
        /* 변동되는 부분 */
        if (type.equals("cheese")) {
            pizza = new CheesePizza();
        } else if (type.equals("greek")) {
            pizza = new GreekPizza();
        } else if (type.equals("pepperoni")) {
            pizza = new PepperoniPizza();
        }
     
        /* 고정되는 부분 */
        pizza.prepare();
        pizza.bake();
        pizza.cut();
        pizza.box();
    }
     
    cs





    변동되는 부분을 캡슐화하여 orderPizza에서 덜어낸다.



     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
     
    public class SimplePizzaFactory {
        public Pizza createPizza(String type) {
            Pizza pizza = null;
     
            switch (type) {
            case "cheese"
                pizza = new CheesePizza();
                break;
                
            case "pepperoni":
                pizza = new PepperoniPizza();
                break;
     
            case "clam":
                pizza = new ClamPizza();
                break;
            
            case "veggie":
                pizza = new VeggiePizza();
                break;
                
            }
            
            return pizza;
        }
    }
     
    cs










    덜어낸 SimplePizzaFactory를 생성하여 피자를 주문한다.


     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
     
    public class PizzaStore {
        SimplePizzaFactory factory;
        public PizzaStore(SimplePizzaFactory factory) {
            this.factory = factory;
        }
        
        public Pizza orderPizza(String type) {
            Pizza pizza = null;
            pizza = factory.createPizza(type);
            pizza.prepare();
            pizza.bake();
            pizza.cut();
            pizza.box();
            
            return pizza;
        }
    }
    cs





    전반적으로 실행 코드를 보도록 하자.



     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    package factory;
     
    public class PizzaMain {
        public static void main(String[] args) {
            SimplePizzaFactory factory = new SimplePizzaFactory();
            PizzaStore store = new PizzaStore(factory);
            Pizza cheesePizza = store.orderPizza("cheese");
        }
    }
     
    cs




    클래스다이어그램을 통해 보자.




     





    다른 예제를 통해서 팩토리 패턴을 살펴보자.




    Human.java

     

    1
    2
    3
    4
    5
    6
    7
    8
     
    package anot_factory;
     
    public interface Human {
        public void Talk();
        public void Walk();
    }
     
    cs



    Boy.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    package anot_factory;
     
    public class Boy implements Human {
     
        @Override
        public void Talk() {
            System.out.println("Boy is talking...");
        }
     
        @Override
        public void Walk() {
            System.out.println("Boy is walking...");
        }
     
    }
     
    cs



    Girl.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    package anot_factory;
     
    public class Girl implements Human {
     
        @Override
        public void Talk() {
            System.out.println("Girl is talking...");
        }
     
        @Override
        public void Walk() {
            System.out.println("Girl is walking...");
        }
     
    }
     
    cs



    HumanFactory.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
     
    package anot_factory;
     
    public class HumanFactory {
        public static Human createHuman(String sex) {
            Human person = null;
     
            if (sex == "boy") {
                person = new Boy();
            } else if (sex == "girl") {
                person = new Girl();
            }
     
            return person;
        }
    }
     
    cs




    HumanMain.java

     

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    package anot_factory;
     
    public class HumanMain {
        public static void main(String[] args) {
            Human boy = HumanFactory.createHuman("boy");
            Human girl = HumanFactory.createHuman("girl");
            
            boy.Talk();
            girl.Talk();
        }
    }
     
    cs




    클래스 다이어그램


     






     





     





    다른 예제:


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    /*
     * factory.cpp
     *
     *  Created on: 2015. 11. 19.
     *      Author: palpit
     */
     
    #include <iostream>
     
    using namespace std;
     
    enum genre {
        ROCK, POP, REGGAE, INVALID
    };
     
    class Music {
    public:
        virtual void song() = 0;
    };
     
    class Rock: public Music {
    public:
        void song() {
            cout << "Nirvana: Smells like a teen spirit " << endl;
        }
    };
     
    class Pop: public Music {
    public:
        void song() {
            cout << "Michael Jackson: Billie Jean" << endl;
        }
    };
     
    class Reggae: public Music {
    public:
        void song() {
            cout << "Bob Marley: No woman, No cry " << endl;
        }
    };
     
    class MusicFactory {
    public:
        Music *getMusic(genre genre) {
            Music *music = NULL;
     
            switch (genre) {
            case ROCK:
                music = new Rock();
                break;
            case POP:
                music = new Pop();
                break;
            case REGGAE:
                music = new Reggae();
                break;
     
            default:
                music = NULL;
                break;
     
            }
     
            return music;
        }
    };
     
    int main(void) {
        MusicFactory *musicFactory = new MusicFactory();
     
        Music *music = musicFactory->getMusic(POP);
     
        cout << "Song: ";
     
        if (music) {
            music->song();
        } else {
            cout << "Wrong selection dude/dudette !!" << endl;
        }
     
        return 0;
    }
     
     
    cs











    댓글

Designed by Tistory.