-
[Design Pattern] 팩토리(factory) 패턴 - 디자인 패턴CSE/Design Pattern 2015. 6. 13. 10:24
Pattern #1 팩토리 패턴
생성자만으로는 개별 객체 생성이 적합하지 않은 경우 사용
목적
- 객체생성을 위한 인터페이스를 정의하는데 있다.
- 어떤 클래스의 인스턴스를 생성할지에 대한 결정은 서브클래스에서 이루어지도록 인스턴스의 책임을 미룬다.
결과
- 다양한 형태의 객체를 반환하는 융통성을 갖게 된다.
1. 팩토리 패턴을 사용하는 이유
생성자 사용할 때의 문제
12345678910Duck duck;if (picnic) {duck = new MallardDuck();} else if (hunting) {duck = DecoyDuck();} else if (inBathTub) {duck = RubberDuck();}cs 새로운 타입이 추가될 때 문제가 된다. -> 계속해서 else if 구문을 추가해서 작성해야 함.
사례 #1 - 피자 스토어
123456789101112131415Pizza 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 메소드를 다시 한 번 보면 변경, 추가, 삭제에 따른 변동이 있는 부분과 고정된 부분이 존재한다.
1234567891011121314151617Pizza 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에서 덜어낸다.
123456789101112131415161718192021222324252627282930public 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를 생성하여 피자를 주문한다.
123456789101112131415161718public 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 전반적으로 실행 코드를 보도록 하자.
12345678910package 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
12345678package anot_factory;public interface Human {public void Talk();public void Walk();}cs Boy.java
1234567891011121314151617package anot_factory;public class Boy implements Human {@Overridepublic void Talk() {System.out.println("Boy is talking...");}@Overridepublic void Walk() {System.out.println("Boy is walking...");}}cs Girl.java
1234567891011121314151617package anot_factory;public class Girl implements Human {@Overridepublic void Talk() {System.out.println("Girl is talking...");}@Overridepublic void Walk() {System.out.println("Girl is walking...");}}cs HumanFactory.java
1234567891011121314151617package 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
12345678910111213package 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 클래스 다이어그램
다른 예제:
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384/** 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 'CSE > Design Pattern' 카테고리의 다른 글
[Design Pattern] 데코레이터(Decorator) 패턴 - 디자인 패턴 (0) 2015.06.13 [Design Pattern] 파써드(Facade) 패턴 (0) 2015.06.13 [Design Pattern] 빌더(Builder) 패턴 - 디자인 패턴 (0) 2015.06.13 [Design Pattern] 추상 팩토리(Abstract factory) 패턴 (0) 2015.06.13 [Design Pattern] 프로토타입(Prototype) 패턴 - 디자인 패턴 (0) 2015.06.13 [Design Pattern] 싱글톤(Singleton) 패턴 - 디자인 패턴 (0) 2015.06.13