1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<code> </code><code>public</code> <code>Pizza orderPizza(String type) {</code>
<code> </code><code>Pizza pizza;</code>
<code>//-------------------------------------------------------------</code>
<code>//---------------------将虛線下代碼提取出來--------------------</code>
<code> </code>
<code> </code><code>if</code><code>(type.equals(</code><code>"cheese"</code><code>))</code>
<code> </code><code>pizza = </code><code>new</code> <code>CheesePizza();</code>
<code> </code><code>else</code> <code>if</code><code>(type.equals(</code><code>"greek"</code><code>))</code>
<code> </code><code>pizza = </code><code>new</code> <code>GreekPizza();</code>
<code> </code><code>else</code> <code>if</code><code>(type.equals(</code><code>"pepperoni"</code><code>))</code>
<code> </code><code>pizza = </code><code>new</code> <code>PepperoniPizza();</code>
<code>//--------------------将虛線上代碼提取出來----------------------</code>
<code>//--------------------------------------------------------------</code>
<code> </code><code>pizza.prepare();</code>
<code> </code><code>pizza.bake();</code>
<code> </code><code>pizza.cut();</code>
<code> </code><code>pizza.box();</code>
<code> </code><code>return</code> <code>pizza;</code>
<code> </code><code>}</code>
這裡有一些要執行個體化的具體類,究竟執行個體化哪個類,要在運作時由一些條件來決定。當看到這樣的代碼,一旦有變化或擴充,就必須重新打開這段代碼進行檢查和修改。通常這樣修改過的代碼将造成部分系統給更難維護和更新,而且也更容易犯錯。應當找出變化的方面,把它們從不變的部分分離出來。别忘了,我們應當面向接口程式設計,代碼改變如下:
<code>public</code> <code>abstract</code> <code>class</code> <code>PizzaStore {</code>
<code> </code><code>pizza = createPizza(type);</code>
<code> </code>
<code> </code><code>protected</code> <code>abstract</code> <code>Pizza createPizza(String type);</code>
<code>}</code>
由工廠專門來處理建立對象的細節,一旦有了工廠,orderPizza()就變成此對象的客戶。orderPizza隻關心從工廠得到一個比薩。
建立一個簡單的工廠,為所有比薩封裝建立對象的代碼:
<code>public</code> <code>class</code> <code>PizzaFactory </code><code>extends</code> <code>PizzaStore {</code>
<code> </code><code>public</code> <code>Pizza createPizza(String type) {</code>
<code> </code>
<code> </code><code>// TODO Auto-generated method stub</code>
<code> </code><code>if</code> <code>(type.equals(</code><code>"cheese"</code><code>)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code><code>(type.equals(</code><code>"greek"</code><code>)) {</code>
<code> </code><code>}</code><code>else</code> <code>if</code><code>(type.equals(</code><code>"pepperoni"</code><code>)) {</code>
<code> </code><code>}</code>
這樣做有什麼好處?似乎隻是把問題搬到另一個對象罷了。别忘了,PizzaFactory可有許多客戶,可能還有PizzaShopMenu(比薩店菜單),HomeDelivery(宅急送)類,會利用這個工廠來取得比薩。把建立對象的代碼封裝到一個類,當以後實作改變時,隻需修改這個類即可。我們正是把具體執行個體化的過程,從客戶的代碼中删除,讓PizzaStore的各個子類負責定義自己的createPizza()方法。
abstract product factoryMethod(String type)
在上例中createPizza就是一個工廠方法。工廠方法是抽象的,是以依賴子類來處理對象的建立;工廠方法必須傳回一個産品,超類中定義的方法,通常使用到工廠方法的傳回值;工廠方法用來處理對象的建立,并将這樣的行為封裝在子類中,這樣客戶程式中關于超類的代碼就和子類對象建立代碼解耦了。
<a href="http://s3.51cto.com/wyfs02/M01/11/C3/wKioL1Lc7LqRR6FBAB4hiIf-3Dw249.jpg" target="_blank"></a>
<a href="http://s3.51cto.com/wyfs02/M02/11/C3/wKioL1Lc7n_DhaqMAB6GQewQvzU064.jpg" target="_blank"></a>
本文轉自 ponpon_ 51CTO部落格,原文連結:http://blog.51cto.com/liuxp0827/1353209,如需轉載請自行聯系原作者