天天看點

建立者模式詳解

你了解建立者模式了嗎 ?   我準備從 How 和 Why 這兩個角度來談談我對建立者模式的了解 .   How to implement Factory and Abstract Factory   對于建立者模式 , 有一點很容易被大多數人所忽視所誤解 , 就是 Factory 模式和 Abstract Factory 模式的差別 . 他們的最重要的差別不是在于 Abstract Factory 是用于建立産品族 , 而 Factory 僅僅用于建立一種類型的産品 . 他們的差別在于一個很重要的思想 : 是采用聚合還是繼承 ? Favor Composition than inheritance. 談到建立者模式大家不自然的就會想到他們的任務都是用于建立對象 . 然而真是這樣嗎 ? 他們僅僅是用于建立對象 ? 讓我們來看看 Gof 書中有關 Factory 的一個例子 . 

建立者模式詳解

注意到了嗎 ? Application 就是一個 Factory, 對于不同的 Document 我們需要擴充不同的 Application 然後 override 它們的 CreateDocument 方法 . 然而 Application 僅僅是建立文檔對象嗎 ? 它還做了一系列的工作 , 将建立的文檔對象添加到文檔清單并打開文檔 . 并且還提供了一個完全和建立無關的打開文檔 (OpenDocument 方法 ) 的功能 . 看看它和你想象中的建立者模式一樣嗎 ? 它可不是僅僅 new 一個對象那麼簡單 . 你注意到了嗎 ? 我估計很多人都沒有注意到這點 , 甚至在呂震宇的文章中 .( 呂兄可别怪我 :P 誰叫你太有名了 )

建立者模式詳解

呂震宇文中的例圖

我們隻看到了 factory 方法 . 然而在 Gof 中的圖是這樣的 :

建立者模式詳解

注意到那個 AnOperation() 了嗎 ?   再來看看 Gof 對 Factory 模式的評價 : There are two common ways to parameterize a system by the classes of objects it creates. One way is to subclass the class that creates the objects; this corresponds to using the Factory Method  pattern. The main drawback of this approach is that it can require creating a new subclass just to change the class of the product. Such changes can cascade. For example, when the product creator is itself created by a factory method, then you have to override its creator as well.   因為 Factory 模式不僅僅是建立一個對象那麼簡單 , 通常還要加上對建立出來的對象做一些操作 ( 比如初始化一些對象的一些屬性 , 把對象和環境關聯起來 )   這樣就算那些操作不變僅僅是因為建立的對象變了 , 你就需要建立一個 Factory.   For example, when the product creator is itself created by a factory method, then you have to override its creator as well. 這句話有點讓人費解 , 讓我們把這句話的示範一下 :

建立者模式詳解

Gof 的意思大概如圖所示 . 就是說僅僅是因為文檔變了我們不僅要為它造一個老爸 (MyApp), 還要連帶為它造一個爺爺 (MyAppCreator). 怎樣才能不造爺爺 ? 使用 Abstract Factory. 這時的工廠就完全是為了建立一個新的對象 , 而不在工廠中對建立的對象做任何操作 . 如下圖所示 :

建立者模式詳解
建立者模式詳解

AppCreator appc = new  AppCreator(); 

建立者模式詳解
建立者模式詳解

Application app = appCreator.Creat( new  MyDocCreator()); 

建立者模式詳解
建立者模式詳解

app.NewDoc(); 

建立者模式詳解

将建立對象的功能 (DocCreator) 從對象的其他操作中 (Application) 完全分離出來作為一個類 , 這樣我們就不需要為每種類型的文檔造爺爺了 . 這個是什麼模式 ?

看看 Gof 的原話 The other way to parameterize a system relies more on object composition: Define an object that's responsible for knowing the class of the product objects, and make it a parameter of the system. This is a key aspect of the Abstract Factory, Builder, and Prototype  patterns. All three involve creating a new "factory object" whose responsibility is to create product objects.   可以發現 Factory Vs Abstract Factory  à    Inheritance Vs Composition   最後再來談談 Why?   Why do we need Creator pattern? 

  相信很多初學者會有這麼一個問題 , 為什麼我們需要建立者模式 ? 然而很多人在向别人介紹建立者模式的時候 , 常常對于這個問題一帶而過 .( 比如我的老師 ).   回答 : 建立者模式是用來建立對象的模式 . 而模式是前人經驗的總結 , 是以建立者模式是一個好東西 .   Do you need answer like this? What can we learn about Creator Pattern From this ? 首先對我來說這不是我需要的答案 , 并且從中我也僅僅知道了建立者模式是用來建立對象的模式 . ( 暈 , 你讀讀這句話不是廢話嘛 )   那麼我的答案是什麼 ?   用代碼說明問題 . ( 源代碼有時勝過千言萬語 )   首先建立了一輛奔馳 . Car car=new Benze(); 突然我們的車變了 , 變成寶馬了 . Ok 我修改一下 . Car car=new BMW();   設想一下在我們的代碼中散布了無數這樣的代碼 . 不止一處 ( 這點很重要 ) 那麼當你以後需要換車的時候 , 是不是需要一一修改我們的建立代碼把 Benze 改成 BMW.   然後我們再用工廠來實作一下 : Car car=benzeFactory().Factory(); 呵呵 這算什麼 ? 沒事找事做 . 如果要換車 , 你不是還要修改原來的代碼改成下面這樣 . Car car=bmwFactory().Factory();   是嗎 ? 如果建立代碼隻有這裡一處可能是這樣 , 但是如果很多地方都要建立的話就不是了 .   CarFactory carFac=new BenzeFactory();   Car car=carFac.Factory(); 當你需要換 Car 的時候你隻需修改一處代碼就是 CarFactory carFac=new XXXFactory(); 其他建立車的地方 , 永遠不變 , 還是 Car car=carFac.Factory(); Ok? 你明白了嗎 ? 我們很難避免修改 , 但是我們要盡量做到隻修改一處 .   不知道 這樣的解釋你是否滿意 . 使用建立者模式是為了提高代碼的可維護性 ( 即應對未來修改的能力 ). 引自:  http://idior.cnblogs.com/archive/2005/04/14/137913.aspx

繼續閱讀