你瞭解創建者模式了嗎? --- 創建者模式詳解

 

你瞭解創建者模式了嗎?

 

我準備從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() 了嗎?

 

再來看看GofFactory模式的評價:

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://www.cnblogs.com/idior/archive/2005/04/14/137913.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章