Simple Factory 심플 팩토리 : 팩토리 패턴의 워밍업 – Head First Design Pattern
by 세계의끝 on 5.26, 2009, under Design Pattern
헤드퍼스트 디자인 패턴 책의 팩토리 패턴(Factory Pattern) 챕터는 70여페이지에 걸쳐 팩토리 패턴의 이름을 가지고 있는 두가지의 패턴을 다루고 있습니다. 팩토리 메서드 패턴과 추상 팩토리 패턴이죠. 그런데 그 전에 팩토리 패턴은 대략 이런것 이라는 식의 워밍업용의 팩토리 패턴을 언급하고 있는데요. 심플 팩토리(Simple Factory) 입니다.
심플 팩토리는 엄밀히 말하면 패턴이라기 보다는 객체지향 프로그래밍을 할때 늘상 사용하게 되는 관용구 같은것이라 패턴으로 취급하지 않는 편입니다. 하지만 뒤에 나올 팩토리 메서드 패턴이나 추상 팩토리 패턴의 기본이 되는 것이라 확실히 짚고 넘어가야 합니다.
심플 팩토리 부분의 코드는 책에 전문이 나와있지 않아 제공되는 자바코드를 직접 컨버팅 하였습니다. 그래서 책의 내용과 약간 다르게 표현된 부분이 있습니다만, 피자는 확실히 주문대로 나옵니다.
팩토리 라는 주제 답게 피자 프랜차이즈를 주제로 예제를 보여주고 있습니다.
이번에는 다른 포스트와는 달리, 호스트코드로부터 피자가 만들어지는 과정을 탐색하면서 들어가보도록 하겠습니다.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package { import flash.display.Sprite; public class Main extends Sprite { public function Main():void { var factory:SimplePizzaFactory = new SimplePizzaFactory() var store:PizzaStore = new PizzaStore( factory ) var pizza:Pizza = store.orderPizza( "cheese" ) trace( "주문한 피자 나왔습니다 :", pizza.getName() ) pizza = store.orderPizza( "veggie" ) trace( "주문한 피자 나왔습니다 :", pizza.getName() ) } } } |
SimplePizzaFactory 객체를 만들고 PizzaStore 객체에 인자로 던집니다. PizzaStore 객체의 orderPizza() 메서드를 이용해 피자를 만들어 내네요.
그럼 SimplePizzaFactory 는 어떻게 되어있는지 보겠습니다.
0 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 | package { public class SimplePizzaFactory { public function createPizza( $type:String ):Pizza { var pizza:Pizza = null; if ( $type == "cheese" ) { pizza = new CheesePizza() } else if ( $type == "pepperoni" ) { pizza = new PepperoniPizza() } else if ( $type == "clam" ) { pizza = new ClamPizza() } else if ( $type == "veggie" ) { pizza = new VeggiePizza() } return pizza; } } } |
네, 그냥 인자로 받은 피자 종류에 따라 구상 클래스로부터 객체를 생성하는 역할만 하고 있습니다. 이 부분은 코드 변경에 대해 닫혀있지 않아서 좋지 않은 구조를 가지고 있다고 할 수 있습니다.[01] 피자가게의 메뉴가 변경이 된다면 이 코드를 직접 고쳐야 하는거죠.
일단 심플 팩토리 이기 때문에 이정도의 구현만 하고 넘어갑니다.
위의 SimplePizzaFactory 를 인자로 받는 PizzaStore 를 보도록 할까요?
0 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 | package { public class PizzaStore { private var factory:SimplePizzaFactory; public function PizzaStore( $factory:SimplePizzaFactory ) { this.factory = $factory; } public function orderPizza( $type:String ):Pizza { var pizza:Pizza; pizza = factory.createPizza( $type ); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } } |
SimplePizzaFactory 객체를 생성자에서 받아 레퍼런스를 저장하고, 호스트코드에서 PizzaStore 객체를 만들때 던진 피자 종류를 인자로 받아 SimplePizzaFactory 의 createPizza() 메서드를 이용해서 Pizza 객체를 만들고 필요한 각 메서드를 순서대로 호출합니다.
그리고 피자가게에 반드시 있어야 할 Pizza 클래스 입니다.
0 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 | package { public class Pizza { protected var name:String; protected var dough:String; protected var sauce:String; protected var toppings:Array = new Array() public function getName():String { return name; } public function prepare():void { var display:String = "n-----"; display += name + "를 준비합니다 -----"; display += "n도우 반죽중..."; display += "n소스 추가중..."; var t:String = ""; for (var i:uint = 0; i < toppings.length; i++ ) { t += toppings[ i ].toString() + ", "; } display += ("n토핑 추가중... : " + t); trace( "n", display ) } public function bake():void { trace( "피자를 굽습니다 :", name ) } public function cut():void { trace( "피자를 자릅니다 :", name ) } public function box():void { trace( "피자를 포장합니다 :", name ) } } } |
코드는 길지만 클래스 구조적으로 하는일은 없습니다. 단지 인스턴스 변수에 필요한 내용을 저장하는것 뿐이죠.
피자 구상 클래스 입니다. SimplePizzaFactory 에서 구상객체를 만들때 사용합니다.
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 | package { public class PepperoniPizza extends Pizza { public function PepperoniPizza() { name = "페퍼로니 피자"; dough = "크러스트"; sauce = "마리나라 소스"; toppings.push( "슬라이스 페퍼로니" ) toppings.push( "슬라이스 양파" ) toppings.push( "으깬 파마산 치즈" ) } } } |
이렇게 심플 팩토리는 구조가 간단합니다.
이 피자가게 심플 픽토리에서 SimplePizzaFactory 는 유일하게 구상 클래스 들을 직접 참조하는 클래스 입니다. PizzaStore 클래스는 직접 피자 객체를 만들지 않고 SimplePizzaFactory 를 이용해서 피자를 만드는 구조로 되어 있습니다.
Simple Factory Example 액션스크립트 코드 다운로드 (212)
- 객체지향 프로그래밍에서의 OCP의 원칙에 따르면 클래스는 확장에 대해서는 열여 있어야 하고(확장가능), 코드 변경에 대해서는 닫혀 있어야(기존에 만든 코드는 변경하지 말것) 합니다. [↑]
Blog under the Creative Commons Attribution-NoDerivs 3.0 License
1월 24th, 2011 on pm 2:58
좋은글 잘읽었습니다.^^