java工廠設(shè)計(jì)模式課件_第1頁(yè)
java工廠設(shè)計(jì)模式課件_第2頁(yè)
java工廠設(shè)計(jì)模式課件_第3頁(yè)
java工廠設(shè)計(jì)模式課件_第4頁(yè)
java工廠設(shè)計(jì)模式課件_第5頁(yè)
已閱讀5頁(yè),還剩44頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、java工廠設(shè)計(jì)模式課件 The Factory Pattern (工廠模式) java工廠設(shè)計(jì)模式課件 學(xué)習(xí)問(wèn)題 n隨著經(jīng)濟(jì)的全球化,一個(gè)軟件可能要在 全球銷售。因此,我們?cè)O(shè)計(jì)的軟件應(yīng)該 能夠通過(guò)簡(jiǎn)單的配置就可以適應(yīng)不同的 國(guó)家。 n本講所學(xué)的知識(shí)將能提供一種有助于解 決此問(wèn)題的方法。 java工廠設(shè)計(jì)模式課件 對(duì)象創(chuàng)建問(wèn)題 n關(guān)于new: n按照面向抽象的設(shè)計(jì)原則,我們應(yīng)該面向 接口編程而不是面向?qū)崿F(xiàn)編程。但是我們 每次使用new時(shí),是不是正在違背這一原 則呢? 我們想用接口但卻必須建立一個(gè) 具體類的實(shí)例 Duck duck = new MallardDuck() java工廠設(shè)計(jì)模式課件

2、 問(wèn)題 n當(dāng)你擁有一組相關(guān)的具體類時(shí),你常常被迫寫 出類似下面的代碼: Duck duck; If (picnic) duck=new MallardDuck(); else if (hunting) duck=new DecoyDuck(); else if (inBathTub) duck=new RubberDuck(); 這樣做的原因是 直到運(yùn)行時(shí)我們 才知道需要實(shí)例 化那個(gè)類。 這樣做的后果是 如果應(yīng)用要做變 化或擴(kuò)展,往往 要修改這段代碼。 這使得維護(hù)困難 并容易引入錯(cuò)誤。 java工廠設(shè)計(jì)模式課件 問(wèn)題在哪里?是new的問(wèn)題嗎? n從技術(shù)上來(lái)說(shuō),new并沒(méi)有任何問(wèn)題。 new是j

3、ava最基本的部分。真正的問(wèn)題在 于“變化” n如果對(duì)接口編程,我們可實(shí)現(xiàn)與許多 “變化”的隔離,因?yàn)橥ㄟ^(guò)多態(tài)機(jī)制, 你的代碼對(duì)于實(shí)現(xiàn)接口的新類依然適用。 但是使用具體類麻煩就來(lái)了,因?yàn)樵黾?新的具體類時(shí)相應(yīng)代碼可能就必須修改。 java工廠設(shè)計(jì)模式課件 怎么辦呢? nDuck duck = new MallardDuck() n上面這段代碼所在的模塊與MallardDuck 模塊形成了耦合。 java工廠設(shè)計(jì)模式課件 再回憶我們前面提出的面向?qū)ο?設(shè)計(jì)的原則 識(shí)別應(yīng)用的變化部分,并將之與固 定的部分相分離。 java工廠設(shè)計(jì)模式課件 區(qū)分變化的部分 下面我們來(lái)看一個(gè)例子 Pizza店 jav

4、a工廠設(shè)計(jì)模式課件 披薩 java工廠設(shè)計(jì)模式課件 PizzaStore類中的一段代碼-訂做pizza Public Class PizzaStore / Pizza orderPizza() Pizza pizza = new Pizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; / 真希望這是 一個(gè)抽象類 或者接口, 可惜抽象類 或接口都不 能被實(shí)例化 而且,我們有許多 種pizza,所以我們 增加一些代碼,來(lái) 確定合適的pizza種 類,然后進(jìn)行制作。 java工廠設(shè)計(jì)模式課件 修改

5、后的代碼 Pizza orderPizza(String type) Pizza pizza; 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(); return pizza; 根據(jù)接受的類型,

6、創(chuàng) 建相應(yīng)的pizza實(shí)例, 并賦值給實(shí)例變量。 (注意:各種pizza實(shí) 現(xiàn)接口Pizza) 傳遞pizza的 類型給方法 orderPizza 每一種pizza子類型都 知道其制作方法 java工廠設(shè)計(jì)模式課件 由于市場(chǎng)競(jìng)爭(zhēng)。 n其他pizza店推出了新產(chǎn)品,我們也得增 加!例如VeggiePizza。 nGreekPizza最近不受歡迎,把它從菜單中 取消。 n于是。 java工廠設(shè)計(jì)模式課件 改!改!改! Pizza orderPizza(String type) Pizza pizza; if (type.equals(“cheese”) pizza = new CheesePizz

7、a(); else if (type.equals(“greek”) pizza = new GreekPizza(); else if (type.equals(“pepperoni”) pizza = new PepperoniPizza(); else if (type.equals(“veggie”) pizza = new VeggiePizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; 變與不變 java工廠設(shè)計(jì)模式課件 變與不變 Pizza orderPizza(String

8、 type) Pizza pizza; if (type.equals(“cheese”) pizza = new CheesePizza(); else if (type.equals(“greek”) pizza = new GreekPizza(); else if (type.equals(“pepperoni”) pizza = new PepperoniPizza(); else if (type.equals(“veggie”) pizza = new VeggiePizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza

9、.box(); return pizza; 這是變化的部分。隨 著Pizza菜單的變化, 這部分要跟著不斷地 變。 這部分是不變的 部分。 java工廠設(shè)計(jì)模式課件 分離 Pizza orderPizza(String type) Pizza pizza; if (type.equals(“cheese”) pizza = new CheesePizza(); else if (type.equals(“greek”) pizza = new GreekPizza(); else if (type.equals(“pepperoni”) pizza = new PepperoniPizza()

10、; else if (type.equals(“veggie”) pizza = new VeggiePizza(); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; 把這部分封裝在一個(gè) 只管如何創(chuàng)建pizza的 對(duì)象中 if (type.equals(“cheese”) pizza = new CheesePizza(); else if (type.equals(“greek”) pizza = new GreekPizza(); else if (type.equals(“pepperoni”)

11、 pizza = new PepperoniPizza(); else if (type.equals(“veggie”) pizza = new VeggiePizza(); 將創(chuàng)建pizza對(duì)象的 代碼從orderPizza方法 中分離出去 專管制作 pizza的對(duì)象 java工廠設(shè)計(jì)模式課件 我們將專管制作pizza的對(duì)象叫做Pizza工廠 Pizza orderPizza(String type) Pizza pizza; pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; PizzaFactor

12、y 要求制作pizza pizza 這樣,orderPizza方法 就成為PizaFactory的客 戶。 java工廠設(shè)計(jì)模式課件 Pizza工廠-SimplePizzaFactory public class SimplePizzaFactory public Pizza createPizza(String type) Pizza pizza=null; if (type.equals(“cheese”) pizza = new CheesePizza(); else if (type.equals(“pepperoni”) pizza = new PepperoniPizza(); e

13、lse if (type.equals(“veggie”) pizza = new VeggiePizza(); return pizza; Pizza工廠中定義了 “生產(chǎn)”pizza的方法。 所有客戶都可以用它來(lái) 實(shí)例化新的pizza對(duì)象 這部分代碼就是 從orderPizza()方 法中抽出來(lái)的。 和原來(lái)的方法一 樣,也是通過(guò)參 數(shù)確定pizza的種 類。 java工廠設(shè)計(jì)模式課件 思考一下! n這看來(lái)好像我們只是把問(wèn)題從一個(gè)對(duì)象推給了 另一個(gè)對(duì)象!這樣做有什么好處呢? n可以解除客戶代碼(PizzaStore)與具體Pizza的 耦合。 nSimplePizzaFactory可以有許多個(gè)

14、客戶,這樣, 當(dāng)實(shí)現(xiàn)改變時(shí)我們只需要修改 SimplePizzaFactory,而不需修改眾多的客戶。 n提高了聚合度,PizzaStore的職責(zé)是使用pizza對(duì) 象, SimplePizzaFactory的職責(zé)是決定創(chuàng)建什么 樣的pizza對(duì)象。 java工廠設(shè)計(jì)模式課件 重寫PizzaStore類 public class PizzaStore SimplePizzaFactory factory; public PizzaStore(SimplePizzaFactory factory) this.factory = factory; public Pizza orderPizza(S

15、tring type) Pizza pizza; pizza=factory.createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; /other methods here java工廠設(shè)計(jì)模式課件 簡(jiǎn)單工廠模式 PizzaStore orderPizza() SimplePizzaFactory createPizza() Pizza Prepare() Bake() Cut() Box() CheesePizza VeggiePizzaClamPizza Pepper

16、oniPizza Pizza可以是 一個(gè)抽象類, 也可以是一個(gè) 接口。 PizzaStore1 orderPizza() 框架 框架的 對(duì)外接口 java工廠設(shè)計(jì)模式課件 簡(jiǎn)單工廠模式 Client orderProduct() SimpleFactory createProduct() AbstractProduct methodOfProduct() Product1 Product2Product3 Productn 有人認(rèn)為這還不 是一個(gè)真正的模 式,只是一種程 序設(shè)計(jì)的習(xí)慣。 java工廠設(shè)計(jì)模式課件 授權(quán)pizza店 n我們的pizza店非常成功,許多人都想開 設(shè)我們的授權(quán)加盟店。

17、 n但是,不同地區(qū)的加盟pizza店可能希望 供應(yīng)不同口味的pizza。怎么解決這個(gè)問(wèn) 題呢? java工廠設(shè)計(jì)模式課件 解決方法之一:建立不同的工廠 n建立不同的工廠:如NYPizzaFactory、 ChicagoPizzaFactory、 CaliforniaPizzaFactory,在PizzaStore中包含相應(yīng)工廠的實(shí)例。其代 碼類似于: /該pizza店提供紐約風(fēng)味的pizza NYPizzaFactory nyFactory=new NYPizzaFactory();/建立一個(gè)生產(chǎn)紐 約風(fēng)味pizza的工廠 PizzaStore nyStore=new PizzaStore(n

18、yFactory);/建立一個(gè)pizza店, 引用紐約風(fēng)味pizza的工廠 nyStore.orderPizza(“Veggie”);/生產(chǎn)的是紐約風(fēng)味的pizza /該pizza店提供芝加哥風(fēng)味的pizza ChicagoPizzaFactory chicagoFactory=new ChicagoPizzaFactory(); PizzaStore chicagoStore=new PizzaStore(chicagoFactory); chicagoStore.orderPizza(“Veggie”); java工廠設(shè)計(jì)模式課件 抽象工廠模式 n這么多工廠,可以再增加抽象層 n讓我們一起

19、來(lái)設(shè)計(jì) java工廠設(shè)計(jì)模式課件 AbstractFactory createProduct() ConcreteFactory createProduct() java工廠設(shè)計(jì)模式課件 另一種解決方法-工廠方法模式 n思路:改寫的PizzaStore,將createPizza() 方法放回到PizzaStore,但是聲明為抽象 方法,然后,為每一種地方風(fēng)味創(chuàng)建一 個(gè)PizzaStore的子類。 java工廠設(shè)計(jì)模式課件 改造后的PizzaStore的代碼 public abstract class PizzaStore public Pizza orderPizza(String type)

20、 Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; abstract Pizza createPizza(String type); 在PizzaStore內(nèi)調(diào)用自 身的一個(gè)方法來(lái)制造 pizza,而不是使用一個(gè) factory對(duì)象 factory對(duì)象成了這里的 一個(gè)抽象方法 下面我們需要PizzaStore的各種子類(對(duì)應(yīng)不同 的地區(qū)風(fēng)味) java工廠設(shè)計(jì)模式課件 讓子類做決定 PizzaStore createPizza() ord

21、erPizza() NYPizzaStore createPizza() ChicagoPizzaStore createPizza() Pizza createPizza(String item) if (item.equals(“奶酪奶酪) return new NYStyleCheesePizza(); else if (item.equals(“蔬菜蔬菜) return new NYStyleVeggiePizza(); else if (item.equals(“卡姆卡姆) return new NYStyleClamPizza(); else if (item.equals(“辣香

22、腸辣香腸) return new NYStylePepperoniPizza(); else return null; java工廠設(shè)計(jì)模式課件 討論:為什么說(shuō)是由子類做決定的? PizzaStore createPizza() orderPizza() NYPizzaStore createPizza() ChicagoPizzaStore createPizza() public abstract class PizzaStore public Pizza orderPizza(String type) Pizza pizza = createPizza(type); pizza.prep

23、are(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; abstract Pizza createPizza(String type); java工廠設(shè)計(jì)模式課件 現(xiàn)在讓我們來(lái)編寫子類NYPizzaStore PizzaStore createPizza() orderPizza() NYPizzaStore createPizza() ChicagoPizzaStore createPizza() public class NYPizzaStore extends PizzaStore Pizza createPizza(St

24、ring item) if (item.equals(“奶酪奶酪) return new NYStyleCheesePizza(); else if (item.equals(“蔬菜蔬菜) return new NYStyleVeggiePizza(); else if (item.equals(“卡姆卡姆) return new NYStyleClamPizza(); else if (item.equals(“辣香腸辣香腸) return new NYStylePepperoniPizza(); else return null; java工廠設(shè)計(jì)模式課件 怎么編寫子類ChicagoPiz

25、zaStore? 試試看 java工廠設(shè)計(jì)模式課件 聲明工廠方法 public abstract class PizzaStore public Pizza orderPizza(String type) Pizza pizza = createPizza(type); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; abstract Pizza createPizza(String type); 實(shí)例化pizza的責(zé) 任現(xiàn)在由一個(gè)方 法承擔(dān)。該方法 相當(dāng)于一個(gè)工廠。 我們稱之為工廠 方法。 Pizz

26、aStore的子類 用createPizza() 方法處理對(duì)象的 實(shí)例化。 java工廠設(shè)計(jì)模式課件 聲明工廠方法 abstract Pizza createPizza(String type); abstract Product factoryMethod(String type); n工廠方法是抽象的,在一個(gè)超類中定義。必須 由子類來(lái)實(shí)現(xiàn)。 n工廠方法返回一個(gè)產(chǎn)品,該產(chǎn)品通常在其所在 類的方法中定義。(如orderPizza()) n工廠方法通常提供參數(shù),用以選擇一個(gè)產(chǎn)品的 不同品種。 n工廠方法將客戶(超類中的方法,如 PizzaStore中的orderPizza())與具體的產(chǎn)品相 隔

27、離。 java工廠設(shè)計(jì)模式課件 工廠方法怎么工作? n假定張三喜歡紐約風(fēng)味的pizza,李四 喜歡芝加哥風(fēng)味的pizza。 n需要相應(yīng)Pizza店的實(shí)例 n調(diào)用orderPizza()訂購(gòu)想要的pizza品種 ncreatePizza()被調(diào)用,并返回pizza到 orderPizza()方法。 n盡管不知道是什么pizza,但orderPizza() 仍知道對(duì)它進(jìn)行后續(xù)處理。 java工廠設(shè)計(jì)模式課件 以張三訂購(gòu)pizza為例 nPizzaStore nyPizzaStore=new NYPizzaStore(); nnyPizzaStore.orderPizza(“cheese”) n在o

28、rderPizza()方法中 Pizza pizza=createPizza (“cheese”) ; n在orderPizza()方法中 pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); java工廠設(shè)計(jì)模式課件 忘記了產(chǎn)品:pizza,先來(lái)個(gè)抽象的 import java.util.ArrayList; public abstract class Pizza String name; String dough; /生面團(tuán) String sauce; ArrayList toppings = new ArrayList(); v

29、oid prepare() System.out.println(Preparing + name); System.out.println(Tossing dough.); System.out.println(Adding sauce.); System.out.println(Adding toppings: ); for (int i = 0; i toppings.size(); i+) System.out.println( + toppings.get(i); void bake() System.out.println(Bake for 25 minutes at 350);

30、void cut() System.out.println(Cutting the pizza into diagonal slices); void box() System.out.println(Place pizza in official PizzaStore box); public String getName() return name; java工廠設(shè)計(jì)模式課件 再來(lái)個(gè)具體的 public class NYStyleCheesePizza extends Pizza public NYStyleCheesePizza() name = NY Style Sauce and C

31、heese Pizza; dough = Thin Crust Dough; sauce = Marinara Sauce; toppings.add(Grated Reggiano Cheese); Marinara (mariners) sauce is an Italian red sauce usually made with tomatoes, garlic, herbs (such as basil), and onion java工廠設(shè)計(jì)模式課件 再來(lái)個(gè)另一風(fēng)味的 public class ChicagoStyleCheesePizza extends Pizza public

32、ChicagoStyleCheesePizza() name = Chicago Style Deep Dish Cheese Pizza; dough = Extra Thick Crust Dough; sauce = Plum Tomato Sauce; toppings.add(Shredded Mozzarella Cheese); void cut() System.out.println(Cutting the pizza into square slices); java工廠設(shè)計(jì)模式課件 測(cè)試主類 public class PizzaTestDrive public stati

33、c void main(String args) PizzaStore nyStore = new NYPizzaStore(); PizzaStore chicagoStore = new ChicagoPizzaStore(); Pizza pizza = nyStore.orderPizza(cheese); System.out.println(“張三 ordered a + pizza.getName() + n); pizza = chicagoStore.orderPizza(cheese); System.out.println(“李四 ordered a + pizza.ge

34、tName() + n); java工廠設(shè)計(jì)模式課件 工廠方法模式中的類 創(chuàng)建者類 The Creator classes PizzaStore createPizza() orderPizza() NYPizzaStore createPizza() ChicagoPizzaStore createPizza() Abstract creator Concrete creators java工廠設(shè)計(jì)模式課件 工廠方法模式中的類 產(chǎn)品類 The Product classes Pizza NYStyleCheesePizzaChicagoStyleCheesePizza createPizza

35、() NYStylePepperoniPizza NYStyleCalmPizza NYStyleVeggiePizza ChicagoStylePepperoniPizza createPizza() ChicagoStyleCalmPizza createPizza() ChicagoStyleVeggiePizza createPizza() Abstract product Concrete products java工廠設(shè)計(jì)模式課件 工廠方法模式的正式定義 n在類中定義一個(gè)用于創(chuàng)建對(duì)象的接口方法,讓 其子類決定實(shí)例化哪一個(gè)類。通過(guò)這種做法, 使得工廠方法的客戶(工廠方法的使用者)不

36、必了解具體應(yīng)該實(shí)例化哪一個(gè)類。 n如: pizza = pizzaStore.orderPizza(cheese); 生產(chǎn)出來(lái)的匹薩是紐約風(fēng)味的還是芝加哥風(fēng)味的取決于pizzaStore引 用的是哪個(gè)PizzaStore的子類 java工廠設(shè)計(jì)模式課件 工廠方法模式的結(jié)構(gòu) Product ConcreteCreator factoryMethod() ConcreteProduct Creator factoryMethod() anOperation java工廠設(shè)計(jì)模式課件 總結(jié):Factory Method模式 n意圖 n定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定 實(shí)例化哪一個(gè)類。工廠方法模式讓一個(gè)類的 實(shí)例化延遲到其子類。使得對(duì)象的創(chuàng)建與對(duì) 象

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論