記 SAF 中抽象工廠的實現

2021-09-07 21:46:37 字數 2759 閱讀 4524

抽象工廠是很常用的一種建立型模式,它的主要作用在於向程式設計師遮蔽了建立物件的複雜細節,在獲取物件時,只需要在工廠類上呼叫 get***(),或者 create***(),便可以得到乙個型別例項,而不是通常所使用的new ***()這種方式。關於抽象工廠更詳細的內容可以參考 奇幻rpg(人物構建與abstract factory模式) 這篇文章。saf 的抽象工廠也是基於gof的這個基本模型,但是做了下面兩個改進:

我們獲得工廠類時,通常還是通過abstractfactory factory = new concretefactory()這種方式獲得。這樣如果我們想更換乙個工廠實體類時,比如說,將上面的concretefactory換成 anothe***ctory,我們需要修改**為 abstractfactory factory = newanothe***ctory(),這樣免不了需要再次重新進行編譯。

實際的流程如下:

客戶端程式呼叫  classfactory.getfactory(string factoryname) 方法,傳入工廠名稱。

getfactory()方法根據型別資訊,使用反射建立型別例項,然後返回該例項。

saf中的另乙個改進是引入了remoting,關於remoting的詳細內容,可以參考 .net中的remoting 這篇文章。有的時候,我們需要使用remoting獲取位於遠端伺服器中的物件,這時往往需要寫一些註冊channel、轉換物件型別的**。saf的抽象工廠將這些細節也遮蔽了起來,只要將獲取遠端物件的位址寫在配置檔案中,比如http://localhost:8989/classfactory,剩下的步驟與使用本地物件別無二致,極大的簡化了操作。

接下來我們看一下**實現。

首先是建立抽象工廠類的體系,新建乙個解決方案classfactory,再其下建立乙個類庫專案 factory,它包含了下面一些類,以構成乙個基本的抽象工廠模式,作為範例:

這裡需要注意的是 productfactory和 product 抽象類均繼承自 marshalbyrefobject 基類,這是因為這兩個類的子類實現有一部分位於客戶端、還有一部分位於伺服器端,為了能從伺服器端向客戶端進行封送(marshal),它們必須宣告為繼承自marshalbyrefobject。

這裡需要注意:因為factory包含了遠端所要提供的物件,所以我們需要引用它;而它也包含了客戶端可以直接建立的物件,所以客戶端也需要引用factory.dll,但是我們不能將factory伺服器端所提供的內容交給客戶端(如果可以的話,我們根本用不著remoting),所以我們在客戶端引用factory之前要遮蔽掉伺服器端實現的內容。如果直接引用專案(伺服器端、客戶端同時引用了factory專案),一是沒有起到服務端、客戶端分離的作用,二是一旦我們遮蔽掉factory專案中的內容,那麼重新生成之後,伺服器端也喪失了這些內容(所以我們在遮蔽部分內容之前將生成好的dll複製到factoryserver的bin目錄下,然後引用之)。

接著,編寫program**,僅僅是根據配置開啟服務而已:

這個類僅僅是為了在客戶端提供乙個型別資訊,以便能夠通過反射建立型別,實際上只要訪問的是伺服器端,那麼這裡永遠都不會丟擲異常,因為這個類實際是在伺服器端建立的。

注意到name屬性為" remote-productfactory-c "的節點,它擁有乙個location屬性,這個屬性儲存了獲取它的遠端位址,用於remoting訪問。

// 結點處理程式,在呼叫 configurationmanager.getsection("sectionname") 自動呼叫這裡

public class classfactorysectionhandler : iconfigurationsectionhandler

}// 結點配置程式

public class classfactoryconfiguration

// 獲取與name屬性匹配的子結點的 type 屬性

public string getfactorytype(string name)

// 獲取與name屬性匹配的子結點的 location 屬性

// location 屬性指定遠端物件的獲取位置

public string getfactorylocation(string name)

}我們只需要注意兩個方法就可以了:getfacotrytype(string name),獲取工廠類的型別,用於通過反射建立型別;getfactorylocation(string name),獲取工廠類的位址,用於remoting。

接下來我們在解決方案下再建立乙個控制台專案,main,它是我們的客戶程式。在其下建立classfactory類,我們的所有客戶端**實際上通過這個類的靜態方法getfactory(string name)獲取工廠類:

public class classfactory

// 根據結點的name屬性建立factory物件

public static object getfactory(string name) else

}catch

return factory;}}

現在我們對**進行一下測試:

在執行之前,先執行服務端,然後再執行客戶端,可以得到下面的輸出結果:

cheap product

---------------------------

color: red

price: 20

expensive product

---------------------------

color: red

price: 100

// 略 ...

press enter to finish

scala實現抽象工廠

package com.linewell.modeldesgin.abstractfactory created by ctao on 2015 8 8.抽象工廠模式 工廠特質 trait skinfactory 按鈕特質 trait button 文字框特質 trait textfield 春天 ...

反射實現抽象工廠

上篇我們說了介面工廠,接下來我們看看抽象工廠 抽象類用abstract修飾,抽象類不能被例項化,抽象方法必須宣告在抽象類中,抽象型別不一定不需存在抽象方法,具體派生類必須覆蓋基類的抽象方法,抽象派生類可以覆蓋基類的抽象方法也可以不覆蓋 這樣我們就實現了在基類中新增error方法,子類中無需新增,只需...

C 實現抽象工廠模式

using system public class fighttank fightiname public class peopletank peopleiname public class fightplane fightiname public class peopleplane peoplei...