最初在設計模式一書中,許多設計模式都鼓勵使用鬆散耦合。要理解這個概念,讓我們最好先談談許多開發人員從事大型系統的艱苦歷程。在更改一個程式碼片段時,就會發生問題,系統其他部分 —— 您曾經認為完全不相關的部分中也有可能出現級聯破壞。
此問題在於緊密耦合 。系統某個部分中的函數和類別嚴重依賴系統的其他部分中函數和類別的行為和結構。您需要一組模式,使這些類別能夠相互通信,但不希望將它們緊密綁定在一起,以避免出現聯鎖。
在大型系統中,許多程式碼依賴少數幾個關鍵類別。需要更改這些類別時,可能會出現困難。例如,假設您有一個從文件讀取的 User 類別。您希望將其更改為從資料庫讀取的其他類,但是,所有的程式碼都引用從檔案讀取的原始類別。這時候,使用工廠模式會很方便。
工廠模式是一種類,它具有為您創建物件的某些方法。您可以使用工廠類別建立對象,而不直接使用 new。這樣,如果您想要更改所建立的物件類型,只需更改該工廠即可。使用該工廠的所有代碼會自動變更。
範例1:顯示工廠類別的一個示列。等式的伺服器端包括兩個部分:資料庫和一組 PHP 頁面,這些頁面可讓您新增回饋、請求回饋清單並取得與特定回饋相關的文章。
interface IUser { function getName(); } class User implements IUser { public function __construct( $id ) { } public function getName() { return "Jack"; } } class UserFactory { public static function Create( $id ) { return new User( $id ); } } $uo = UserFactory::Create( 1 ); echo( $uo->getName()."\n" ); ?>
IUser介面定義使用者物件應執行什麼操作。 IUser 的實作稱為 User,UserFactory 工廠類別則建立 IUser 物件。此關係可用圖1中的UML 表示。
圖1. 工廠類別及其相關IUser 介面和使用者類別
如果您使用php 解釋器在命令列上執行此程式碼,將得到以下結果:
% php factory1.php Jack %
測試程式碼會向工廠請求User 物件,並輸出getName 方法的結果。
有一種工廠模式的變體使用工廠方法。類別中的這些公共靜態方法建構該類型的物件。如果建立此類型的物件非常重要,此方法非常有用。例如,假設您需要先建立對象,然後設定許多屬性。此版本的工廠模式會將該進程封裝在單一位置中,這樣,不用複製複雜的初始化程式碼,也不必將複製好的程式碼在在程式碼庫中到處貼上。
範例2 顯示使用工廠方法的一個範例。
interface IUser { function getName(); } class User implements IUser { public static function Load( $id ) { return new User( $id ); } public static function Create( ) { return new User( null ); } public function __construct( $id ) { } public function getName() { return "Jack"; } } $uo = User::Load( 1 ); echo( $uo->getName()."\n" ); ?>
這段程式碼要簡單得多。它只有一個介面 IUser 和一個實作此介面的 User 類別。 User 類別有兩個建立物件的靜態方法。此關係可用圖 2 中的 UML 表示。
圖2. IUser 介面和帶有工廠方法的user 類別
在命令列中執行腳本產生的結果與清單1 的結果相同,如下所示:
% php factory2.php Jack %
如上所述,有時此類模式在規模較小的環境中似乎有些大材小用。不過,最好還是學習這種紮實的編碼形式,以便應用於任意規模的專案。
更多PHP設計模式漫談之工廠模式相關文章請關注PHP中文網!