在面向對象的程序設計中,某一功能的實現往往是依賴多個類的協同工作,這當中不必可避免的會有一個核心的關鍵類,非關鍵類對關鍵類的依賴程度比較高(耦合比較緊),關鍵類的變動會景響到非關鍵類與其通信。比如在某個MIS系統中,用戶數據是存儲在文件中的,那麼所有數據的讀取與保存都依賴與那和與文件進行通信的類。突然某一天客戶說要將數據存儲到數據庫中,那麼我們是必要找出所有使用這些與文件通信的類的代碼,並使用新寫的與數據庫通信的類將其替換掉。這個改動量是可想而知的。那麼有沒有一種好的設計模式能夠降低這種情況下的代碼改動量呢?
答案是肯定的。使用工廠模式。我們可以定義一個工廠類,提供一系列的創造對象的方法,代替類似TObject.Create的代碼,降低類與類之間的耦合。
我們就以前面講到的情況為例,來說明工廠模式的使用。在系統中我們已經定義了一個負責數據讀取的抽像類TDataReader和負責數據保存的抽象類TDataWriter,並分別派生了文件讀取類TFileDataReader和文件保存類TFileDataWriter。

//此處僅為說明,其他定義省略

type

TDataReader = class

private

.......

protected

.......

public

.......

procedure Read; virtual; abstract;

.......

end;


TDataWriter = class

private

.......

protected

.......

public

.......

procedure Write; virtual; abstract;

.......

end;


TFileDataReader = class(TDataReader)

private

.......

protected

.......

public

.......

procedure Read; override;

.......

end;


TFileDataWriter = class(TDataWriter)

private

.......

protected

.......

public .......

procedure Write; override;

.......

end;
在重構這前,凡是用到數據讀取與保存的地方,都是使用類似下面的代碼

var

Reader: TFileDataReader;

begin

......
Reader := TFileDataReader.Create;

Reader.Read;

......

end;



var

Writer: TFileDataWriter;

begin

......
Writer := TFileDataWriter.Create;
Writer.Write;

......

end;
現在客戶要求我們將所有的數據存儲到數據庫中,就意味著我們要再分別從TDataReader類和TDataWriter類派生出兩個與數據庫通信的類TDBDataReader和TDBDataWriter(之前良好的類繼承設計使我們在此省下了許多修工作),然後將類似上面的的Reader和Writer的構建語句改為
Reader := TDBDataReader.Crette;

Writer := TDBDataWriter.Create;
這樣的改動也能達到客戶的要求,但我們誰也不能保證在此之後不會再有任何的變化,為了不讓噩夢重演,我們決定不使用這種修改方式。而是定義一個工廠類,負責創建出我們需要的數據讀取類和保存類,即使將來再有變化,我們的修改也僅限於在工廠類內部的改動。

Type

TDataReaderFactory = class

public

function CreatReader: TDataReader;

end;


TDataWriterFactory = class

public

function CreateWriter: TDataWriter;

end;


implementation

...{ TDataReaderFactory }


function TDataReaderFactory.CreatReader: TDataReader;

begin

Result := TDBDataReader.Create;

end;



...{ TDataWriterFactory }


function TDataWriterFactory.CreateWriter: TDataWriter;

begin

Result := TDBDataWriter.Create;

end;
在使用到數據讀寫類的地方,將代碼改為
Reader := TDataReaderFactory.CretteReader;

Writer := TDataWriterFactory.CreateWriter;
至此,我們就通過工廠模式實現了客戶端代碼與數據存取類的松散耦合,也為將來的再修改提供了靈活性。