參考:大話設計模式
型態:創建型模式/生成模式。
定義:提供一個建立一系列相關或相互依賴物件的介面(接口) ,而無需指定他們具體的類別。
使用時機: 需要一組可以隨時抽換的元件,並且希望可以簡單的一次抽換。
結構圖:來源
說明:
「AbstractProductA」和「AbstractProductB」是兩個抽象產品,它們都有多種不同的實現。
「Product 」為抽象產品的具體實現。
「AbstractFactory 」抽象工廠介面,它裡面應該包含所以的產品建立的抽象方法。
「 ConcreteFactory」具體工廠。
========================================================================================================
狀況:有一個專案,對於資料的存取,我們希望實現多資料庫,不侷限於某一個資料庫。
程式碼範例(模擬)
設定兩個類別表示為資料表
撰寫 IUser 與 IDepartment (此為 AbstractProductA 與 AbstractProductB)
實現各產品
抽象工廠與各工廠的實現
客戶端程式碼
結果
=================================================================================================
根據以上,體驗出以下狀況
我們封裝 (new)。
第一:我們無法防止需求的更改,那我們希望讓改動變得最小,如果要更改資料庫存取,只需要更改具體工廠就可以做到。
第二:讓具體建立實體過程與用戶端分離,用戶端都是透過它們的抽象介面操縱實體,無須知道是 SQL Server 或是 Access 。
缺點:
當我們需要加入一個資料表,比方說 (Project),就必須撰寫 IProject、SqlserverProgject、AccessProject,還需要更改
IFactory、SqlserveerFactory、AccessFactory 才可以實現。
改進一:
於是我們使用「簡單工廠」來改進工廠類別,使用 DataAccess 類別。
Client 端,程式碼
結果
===============================================================================================
改進一,讓我們的客戶端程式碼不在受改動資料庫的影響了,只是,若增加一個 Oracle 資料庫存取,現在反而
需要在 DataAccess 類別中的每個方法加入 switch case 來判別。
改進二:使用「反射原理」,讓物件的實體化由編譯時轉為執行時。
是的到目前為止,似乎有看到一絲絲的物件導向,客戶端與資料庫實作分開,若增加 Project 產品時,也只需要增加三個與
Project 相關的類別,再修改 DataAccess 增加一個靜態方法取得 IProject 接口;只是有點小遺憾,似乎更換當前欲使用的
資料庫存取時,還是要進去改程式(改 db 這個字串的值) 重新編譯。
=================================================================================================
改進三:用反射 + 設定檔實現資料存取程式。
加入 App.config 檔
再次調整 DataAccess 類別
結果
最後有一種東西叫做「依賴注入」 (Dependency Injection),也可以幫助我們處理「實體化」的動作,
可參考 In91、Face Bug、Pete.NET、黃忠成。
Reference
0 Comments:
張貼留言