2010-01-18 55 views
76

這讓我困惑,用最簡單的話來說,它有什麼作用?假裝你正在向你的母親或某人求解。什麼是PHP中的工廠設計模式?

+105

我媽媽不會明白反正... –

+6

@JasonDavis我一直回答你的問題......我開始感覺自己像一個纏擾者。 –

回答

159

工廠創建一個對象。所以,如果你想建立

class A{ 
    public $classb; 
    public $classc; 
    public function __construct($classb, $classc) 
    { 
     $this->classb = $classb; 
     $this->classc = $classc; 
    } 
    } 

你不會想依靠不得不做創建對象

$obj = new ClassA(new ClassB, new Class C); 

這就是工廠會來在下面的代碼每次我們定義一個工廠的照顧,對我們:

class Factory{ 
    public function build() 
    { 
     $classc = $this->buildC(); 
     $classb = $this->buildB(); 
     return $this->buildA($classb, $classc); 

    } 

    public function buildA($classb, $classc) 
    { 
     return new ClassA($classb, $classc); 
    } 

    public function buildB() 
    { 
     return new ClassB; 
    } 

    public function buildC() 
    { 
     return new ClassC; 
    } 
} 

現在我們所要做的就是

$factory = new Factory; 
$obj  = $factory->build(); 

真正的優勢是當你想改變班級。比方說,我們希望在不同的ClassC經過:

class Factory_New extends Factory{ 
    public function buildC(){ 
     return new ClassD; 
    } 
} 

或新ClassB的:

class Factory_New2 extends Factory{ 
    public function buildB(){ 
     return new ClassE; 
    } 
} 

現在我們可以使用繼承輕鬆修改類是如何創建的,就擺在一組不同的類。

一個很好的例子可能是該用戶等級:

class User{ 
    public $data; 
    public function __construct($data) 
    { 
     $this->data = $data; 
    } 
} 

$data這個類是我們用來存儲我們的數據的類。現在對於這個類,讓我們說我們使用Session來存儲我們的數據。該工廠是這樣的:

class Factory{ 
    public function build() 
    { 
     $data = $this->buildData(); 
     return $this->buildUser($data); 
    } 

    public function buildData() 
    { 
     return SessionObject(); 
    } 

    public function buildUser($data) 
    { 
     return User($data); 
    } 
} 

現在,讓我們說不是我們想我們所有的數據存儲在數據庫中,這是非常簡單的更改:

class Factory_New extends Factory{ 
    public function buildData() 
    { 
     return DatabaseObject(); 
    } 
} 

工廠是一家設計我們用來控制如何將對象放在一起的模式,並且使用正確的工廠模式允許我們創建我們需要的自定義對象。

+10

+1個很好的例子 – Parrots

+2

這是很多打字。現在我必須在某個時候將它放到我的wiki上。 –

+0

謝謝,這有助於一些 – JasonDavis

16

像現實生活中的工廠,它創造的東西,並返回它。

想象這樣的事情

$joe = new Joe(); 
$joe->say('hello'); 

或工廠方法

Joe::Factory()->say('hello'); 

工廠方法將創建一個新的實例並返回它的實現。

+1

不錯的例子,令我驚訝的是,這種模式的實現方式有多種多樣。靜態調用時,我假設可以獲取對實例的引用,以便稍後重用相同的實例?即$ joe = Joe :: Factory() - > say('hello'); – stefgosselin

+0

當然在5.6也可以做(新喬()) - >說('你好'); – Pancho

1

一般來說,「工廠」會產生一些東西:在面向對象編程的情況下,「工廠設計模式」產生對象。

如果是PHP,C#或任何其他面向對象的語言,這並不重要。

1

工廠設計模式(工廠模式)用於鬆耦合。像工廠的意義一樣,數據到工廠(產生數據)給最終用戶。通過這種方式,工廠打破了數據源與數據處理之間的緊密耦合。

0

這個答案與Daniel White說的使用工廠創建工廠模式的MySQL連接的其他文章有關。

對於MySQL連接,我寧願使用單例模式,因爲您想使用相同的連接 來訪問數據庫而不是創建另一個連接。

0

的經典方法實例化一個對象是:

$Object=new ClassName(); 

PHP必須使用以下語法動態創建變量名對象的能力:

$Object=new $classname; 

其中變量$類名包含類的名字想要實例化。

所以經典的對象保會是什麼樣子:

function getInstance($classname) 
{ 
    if($classname==='Customer') 
    { 
    $Object=new Customer(); 
    } 
    elseif($classname==='Product') 
    { 
    $Object=new Product(); 
    } 
    return $Object; 
} 

,如果你調用的getInstance(「產品」)函數這個工廠將創建並返回Product對象。否則,如果您調用getInstance('Customer')函數,則此工廠將創建並返回Customer類型對象(由Customer()類創建)。

沒有必要對任何更多的,可以發送「產品」或「客戶」(現有類的確切名稱)作爲動態實例變量的值:

$classname='Product'; 
$Object1=new $classname; //this will instantiate new Product() 

$classname='Customer'; 
$Object2=new $classname; //this will instantiate new Customer() 
0

爲了記錄在案,在簡單的話,像@Pindatjuh這樣的工廠說,會返回一個對象。

那麼,構造函數有什麼區別? (也是這樣)

  1. 構造函數使用他自己的實例。
  2. 我想要的東西更高級一些,我不想膨脹對象(或添加依賴項)。
  3. 構造函數在創建每個實例時調用。有時你不想要那樣。

    例如,假設每次創建類Account的對象,我從數據庫中讀取一個文件並將其用作模板。

使用構造函數:

class Account { 
     var $user; 
     var $pwd; 
     var ... 
     public __construct() { 
     // here i read from the file 
     // and many other stuff 
     } 
} 

使用工廠:

class Account { 
     var $user; 
     var $pwd; 
     var ... 
} 
class AccountFactory { 
     public static Create() { 
     $obj=new Account(); 
     // here we read the file and more stuff. 
     return $obj; 
     }