設計模式之: 原廠模式

來源:互聯網
上載者:User

標籤:

      作為一種建立型設計模式, Factory 方法(Factory Method)模式就是要建立"某種東西". 對於Factory 方法模式, 要建立的"東西"是一個產品,這個產品與建立它的類之間不存在綁定.實際上,為了保持這種松耦合,客戶會通過一個工廠發出請求. 再由工廠建立所請求的產品.也可以換種方式考慮, 利用Factory 方法模式, 要求者只發出請求, 而不具體建立產品.

 工廠的工作先建立一個工廠的介面Factory.php
<?phpabstract class Factory{    //抽象的建立對象的方法    protected abstract function createProduct();    //該方法調用createProduct方法返回一個產品對象.    public function start()    {         return $this->createProduct();    }}
start方法返回一個產品,該方法調用createProduct方法完成產生產品的操作.所以createProduct的具體實現要構建並返回一個按Product介面實現的產品對象.比如產品都有一個共同的方法getProperties(), 以下是對應Product介面Product.php
<?php//產品介面interface Product{    public function getProperties();}
接著, 我們要建立兩個工廠,文本工廠TextFactory和映像工廠phptoFactoryTextFactory.php
<?phpinclude_once(‘Factory.php‘);include_once(‘TextProduct.php‘);class TextFactory extends Factory{    protected function createProduct()    {        $product = new TextProduct();        return $product->getProperties();    }}
PhotoFactory.php
<?phpinclude_once(‘Factory.php‘);include_once(‘PhotoProduct.php‘);class PhotoFactory extends Factory{    protected function createProduct()    {        $product = new PhotoProduct();        return $product->getProperties();    }}
可以看到,在Factory 方法的實現中, getProperties方法引入了多態(polymorphism), 將用這個方法返回"文本"或"映像". 同一個getProperties()有多個(poly)不同的形態(morphs), 這就是多態.在這種情況下, 其中一種形式返迴文本, 而另一種返回映像.可以在properties這個實現中放入你想要的任何東西,Factory 方法設計將會建立這個對象, 並把他返回給Client使用.下面的是兩個產品的實現TextProduct.php
<?phpinclude_once(‘Product.php‘);class TextProduct implements Product{    public function getProperties()    {        return "這裡是文本產品";    }}
PhotoProduct.php
<?phpinclude_once(‘Product.php‘);class PhotoProduct implements Product{    //這是產品具有的方法    public function getProperties()    {        return "這裡是映像產品";    }}
這兩個產品實現了Product介面中的抽象方法getProperties(), 客戶(Client)我們並不希望客戶直接做出產品請求.實際上, 我們希望客戶通過Factory工廠介面做出請求.這樣一來,如果以後我們增加了產品或者工廠, 客戶可以做同樣的請求來得到更多類型的產品 , 而不會破壞這個應用:Client.php
<?phpinclude_once(‘PhotoFactory.php‘);include_once(‘TextFactory.php‘);class Client{    public function __construct()    {        $this->somePhotoObject = new PhotoFactory();        echo $this->somePhotoObject->start() . ‘<br />‘;        $this->someTextObject = new TextFactory();        echo $this->someTextObject->start() . ‘<br />‘;    }}$worker = new Client();
運行Client.php, 得到下面的結果
這裡是映像產品這裡是文本產品
注意: Client對象並沒有向產品直接做出請求, 而是通過工廠來請求. 重要的是, 客戶並不實現產品特性, 而留給產品實現來體現. 調整產品設計模式的真正價值並不是提高操作的速度, 而是加快開發的速度. 如果現在需求變化了, 需要對映像產品做出修改, 只需要修改相應的產品PhotoProduct的getProperties方法即可對象的改變看起來很簡單 不過Product的getProperties()方法仍保持相同的介面,請求工廠返回一個屬性對象 增加新產品和參數化請求問題來了,如果要增加更多的映像和文本說明, 有沒有必要每次增加一個新的地區就增加一個新的具體的工廠類?這意味著要為每個新地區增加一個新工廠和產品.於是,我們引進了參數化工廠設計模式參數化工廠設計模式和一般的工廠設計模式的主要區別之一是客戶包含工廠和產品的引用. 在參數化請求中, Client類必須指定產品, 而不是產品工廠. createProduct()操作中的參數是由客戶傳入一個產品; 所以客戶必須指出它想要的具體產品. 不過, 這個請求仍然是通過工廠介面Factory發出的. 所以, 儘管客戶包含一個產品引用, 但通過Factory, 客戶仍然與產品分離.  一個工廠多個產品(參數化Factory 方法)對於大多數請求, 參數化Factory 方法更為簡單, 因為客戶只需要處理一個具體工廠.Factory 方法操作有一個參數,指示需要建立的產品.而在原來的設計中, 每個產品都有自己的工廠, 不需要另個傳遞參數; 產品實現依賴於各個產品特定的工廠.新工廠介面Factory.php
<?phpabstract class Factory{    //抽象的建立對象的方法    protected abstract function createProduct(Product $product);    //該方法由factoryMethod方法返回一個產品對象.    public function start($product)    {         return $this->createProduct($product);    }}
在這個新的Factory介面中可以看到, create()和start()都需要一個參數,指定一個Product對象, 而不是Product介面的一個特定實現, 所以可以接受任何Product的具體執行個體. 工廠具體實現具體的建立者類CommonFactory實現了createProduct(),如下CommonFactory.php
<?phpinclude_once(‘Factory.php‘);include_once(‘Product.php‘);class CommonFactory extends Factory{    protected function createProduct(Product $product)    {        return $product->getProperties();    }}
這個類調用Product的方法getProperties將產品返回給客戶. 新產品具體產品的變化並不會改變原來的Product介面,還是原來的代碼
<?php//產品介面interface Product{    public function getProperties();}
例如, 現在有一個鋼筆產品PenProductPenProduct.php
<?phpinclude_once(‘Product.php‘);class PenProduct implements Product{    public function getProperties()    {        return "鋼筆產品";    }}
 客戶Clent(有參數)
<?phpinclude_once(‘CommonFactory.php‘);include_once(‘PenProduct.php‘);class Client{    public function __construct()    {        $commonFactory = new CommonFactory();        echo $commonFactory->start(new PenProduct());    }}$worker = new Client();
運行後輸出
鋼筆產品
以後如果開發出了新的產品, 只需要建立對應的產品類, 然後客戶指定想要的新產品 , 即可返回客戶需要的產品.  總結:產品改變: 介面不變使用設計模式的一大好處就是可以很容易地對類做出改變, 而不會破壞更大的程式. 之所以能夠容易地做出改變, 秘訣在於保持介面不變, 而只改變內容. 

設計模式之: 原廠模式

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.