在《你是否了解PHP設計模式》一文中,我們曾簡單介紹過工廠模式,今天我們再來詳細看看PHP開發中工廠模式的應用場景。
欲了解更多關於PHP設計模式的內容,歡迎訪問:PHP設計模式漫談
最初在設計模式一書中,許多設計模式都鼓勵使用松散耦合。要理解這個概念,讓我們最好談一下許多開發人員從事大型系統的艱苦歷程。在更改一個代碼片段時,就會發生問題,系統其他部分 —— 您曾認為完全不相關的部分中也有可能出現級聯破壞。
該問題在於緊密耦合 。系統某個部分中的函數和類嚴重依賴於系統的其他部分中函數和類的行為和結構。您需要一組模式,使這些類能夠相互通信,但不希望將它們緊密綁定在一起,以避免出現聯鎖。
在大型系統中,許多代碼依賴於少數幾個關鍵類。需要更改這些類時,可能會出現困難。例如,假設您有一個從文件讀取的 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
- %
如上所述,有時此類模式在規模較小的環境中似乎有些大材小用。不過,最好還是學習這種扎實的編碼形式,以便應用於任意規模的項目中。