[問題] 為什麼工廠方法模式的實作要用繼承的?

看板java作者 (全新開始)時間15年前 (2010/08/29 01:43), 編輯推噓2(204)
留言6則, 3人參與, 最新討論串1/1
O'Relly的head first design patterns有些例子不錯, 但Factory Method這邊我看不太懂意義在哪.... 想麻煩大家解答一下︰ 書上一開始從Simple Factory模式著手,接著用現成的案例延伸到工廠方法模式。 首先他們用pizza類比為工廠產品,PizzaShop負責丟出產品生產與加工後的結果 而SimpleFactory則作為PizzaShop類別的建構子參數,簡單說就是這樣︰ public PizzaShop(SimpleFactory simpleFactory){ this.simpleFactory = simpleFactory; } public Pizza orderPizza(){ Pizza pizza = simpleFactory.createPizza(); //以上是物件的生產過程 以下是處理物件的SOP流程 pizza.bake(); pizza.box(); return pizza; } 到這邊我都明白這樣做的用意︰ 產生物件與處理物件的SOP流程應該要分開,這樣才不會改一項就動到整個類別。 可是當這例子延伸到工廠方法模式之後,我就不明白為什麼要定義抽象方法? 工廠模式下,PizzaShop變成抽象類別 public Pizza orderPizza(){ Pizza pizza = createPizza(); //內容和上個例子相同 故省略 } public abstract Pizza createPizza(){ //交給次類別實作 } 書上在這邊是說,PizzaShop類別不需要了解次類別的實作方式就能取得物件。 因此,當產生物件的工廠有好幾種時,就不用像簡單工廠模式那樣, 需要產生多種參數不同的建構式給不同的工廠類別。 選擇實作createPizza次類別的同時,也就決定了產生物件的工廠種類。 但我的問題是,PizzaShop類別可以透過泛型,統一所有工廠類別的呼叫方法, 那為什麼要在PizzaShop設計抽象方法呢? 例如︰ public class PizzaFactory{ public Pizza createPizza(){ //繼承後可覆寫的內容,或是createPizza直接設計為抽象類別 } } public class PizzaShop<F extends PizzaFactory>{ private F factory; public PizzaShop(F factory){ this.factory = factory; } //建構式 public Pizza orderPizza(){ Pizza pizza = factory.createPizza(); //下略 一樣是處理pizza的SOP流程 } } 寫成這樣,可以同時搞定簡單工廠模式的目地--生產與加工分離, 而且還能彈性地決定生產物件的工廠種類--也就是工廠方法模式想達到的目地, 同時還可以讓物件工廠彼此的生產過程都能有些不同,不需限制細節。 因此我不明白工廠方法模式搞到這麼複雜的意義在哪裡....? 他們到底是想鬆綁哪些物件之間的依賴關係啊? 工廠方法模式的精髓是在哪裡呢? 還是說,這個模式的發展背景是在Java還沒有泛型的年代, 他們只好用這個模式來解決問題? -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 61.231.147.11

08/29 03:58, , 1F
你或許可以去查一下 interface 的 method 是...
08/29 03:58, 1F

08/29 07:02, , 2F
沒事,我只是不太熟泛型罷了.... 給人貼上interface的基礎定義實在很冏.... 最後的例子原先是用泛型內繼承寫的,寫了以後,想說看能不能增加工廠類別 實作上的彈性,於是直覺地以為可以限制泛型裡填入的類別都實作特定介面 供orderPizza()呼叫就好,而不必非得要繼承自某個物件.... 結果我卻忘記泛型裡面不能implements interface,現在我改回原本構想的樣子。 只是改了以後的物件操作方式就和工廠方法模式類似了....

08/29 12:00, , 4F
抽象方法會比泛型複雜嗎!?
08/29 12:00, 4F
哈,是沒錯啦,泛型沒有比抽象方法單純....而且潛藏一些初始化過程不當使用的危險 不過原本例子改回當初構想的樣子之後,用哪種方法都沒有什麼本質上的差別。 我想應該就可以不用再討論用哪種方法實作工廠方法比較好囉.... ※ 編輯: dream1124 來自: 61.228.46.154 (08/29 12:08)

08/29 12:11, , 5F
那建議您重寫一個問題唄. 不然後續想回的人, 有點難理解
08/29 12:11, 5F

08/29 12:59, , 6F
潛藏一些初始化過程不當使用的危險=>不太明白, 有例子嗎?
08/29 12:59, 6F
文章代碼(AID): #1CUKhIhg (java)