聲明:我發布本章節主要是和大家分享這本書裡的知識點,如果涉及到了侵權請作者或是相關人士留言,我會刪除。
Factory Method模式是應用最為廣泛的設計模式,畢竟他負責了一系列對象的建立,而對象的建立正是物件導向編程中最為繁瑣的行為。《設計模式》一書寫到,“Factory Method模式使一個類的執行個體化延遲到子類。”準確的說,Factory Method模式是將建立對象執行個體的責任,轉移到了工廠類中,並利用抽象原理,將執行個體化行為延遲到具體工廠類。
"嫁禍江東"之計
在物件導向的設計中,對象的管理是其核心所在,其中,對象的建立是對象管理的第一步。對象的建立非常簡單,在C#中,只需使用new操作符調用對象的構造方法即可,因此,管理對象最重要的是掌握建立對象的時機。
我們首先從對象的特徵來看。代表抽象意思的類型,如介面和抽象類別,是不能建立對象執行個體的,這意味著我們要建立的對象都是與物件類型有關。也就是說,對象的建立工作必然涉及到設計中的實現細節,從而導致建立者與具體的被建立這之間耦合度增強。舉例來說,如果在一個項目中需要建立一些繪圖物件,例如Circle,Square圖形,它們的結構如所示。
這個類結構非常符合物件導向思想,他通過IShape介面將Square和Circle對象抽象出來。根據多態的原理,我們可以在程式中利用IShape介面代替具體的Square和Circle類,從而將具體的物件類型綁定留到運行時,但由於介面對象是不能建立的,一旦項目需求建立IShape類型的對象,就必然要針對具體的類對象進行建立操作。例如:IShape shape=new Square();
如果是開發一個圖形工具,諸如Square和Circle之類對象的建立工作必然非常頻繁。可以設想,在這個項目的各個摸塊中,如果大量充斥著如上程式碼,那麼導致的結果是各個模組無法與Square具體對象解耦。當我們需要改變建立的對象為Circle時,就必須修改所以調用new Square()操作的模組。這無疑加大了修改的工作量,同時也導致了項目的不可擴充性,以及模組的不可重用性;而對於繪圖物件的抽象IShape介面來說,也成為了不必要且失敗的設計。
我們的目的是要將這種變化給項目帶來的災難槍殺在搖籃之中,此時就需要利用“封裝變化”的原理。我們可以引入Factory Method模式對對象的建立行為進行封裝。IShape類型的對象是工廠要生產的產品。在Factory Method模式中,工廠對象的結構應與產品的結構平行,並與之一一對應。既然具體的產品對象有兩種,相對應的具體工廠對象也應該是兩個,既SquareFactory和CircleFactory;同時,還應該為這兩個工廠抽象出一個共同的工廠介面IShapeFactory。
實現代碼如下: 1namespace DonOfDesign.FactoryPattern.GraphicLib
2{
3 public interface IShapeFactory
4 {
5 IShape CreateShape();
6 }
7}
8----------------------------------------------
9namespace DonOfDesign.FactoryPattern.GraphicLib
10{
11 public class SquareFactory : IShapeFactory
12 {
13 public IShape CreateShape()
14 {
15 return new Square();
16 }
17 }
18}
19----------------------------------------------
20namespace DonOfDesign.FactoryPattern.GraphicLib
21{
22 public class CircleFactory : IShapeFactory
23 {
24 public IShape CreateShape()
25 {
26 return new Circle();
27 }
28 }
29}
30
31
Factory Method模式實現了對象的建立封裝,將建立具體產品對象的代碼全部轉移到了各自的工廠對象中,並在CreateShape方法中實現,整個結構如:
CreateShape方法的返回對象是IShape介面類型,這就有效地避免了工廠對象與具體產品對象的依賴,使得建立者與被建立者實現瞭解耦.
我想,真正的智者是不會被表象所迷惑的.事實上,Factory Method模式的引入,是一種"嫁禍江東"的伎倆,他依舊無法擺脫的職責轉交給工廠對象,然而在工廠類的結構中,依舊存在具體的工廠類對象.我門解出了模組與具體圖象的依賴,卻又增加了對具體工廠對象的依賴,這會給我們的設計帶來何種益處?
讓我們從對象的建立頻率來分析.對於一個圖形分析工具而言,IShape對象的建立無疑是頻繁的,最大的可能行就在這個項目的各個模組中都可能存在建立IShape對象的需要.工廠對象則不盡然,我門完全可以集中一個模組中,初始化該工廠對象,並在需要IShape對象的時候,直接調用工廠執行個體CreateShape方法就可以達到目的.
因此,引入工廠對象並不是簡單的為產品建立相應的工廠,而是要注意劃分各個模組的職責,將工廠對象的建立放到合適的地方。最佳方案莫過於將建立工廠對象的職責集中起來,放到一個模組中;而不是在需要建立產品時,才建立工廠對象。錯誤的例子是在建立產品時將工廠對象的建立與產品對象的建立放在一起,然後分布在各個模組中。這對於引入Factory Method模式來說,無非是畫蛇添足。
範例程式碼下載:FactoryMetod.rar