您好,登錄后才能下訂單哦!
小編給大家分享一下PHP設(shè)計(jì)模式之工廠模式怎么用,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!
工廠模式(Factory Design Pattern)作為一種創(chuàng)建型設(shè)計(jì)模式, 遵循了開放-封閉原則, 對修改封閉, 對擴(kuò)展開放. 工廠方法(Factory Method)模式就是要創(chuàng)建"某種東西". 對于工廠方法模式, 要創(chuàng)建的"東西"是一個(gè)產(chǎn)品,這個(gè)產(chǎn)品與創(chuàng)建它的類之間不存在綁定.實(shí)際上,為了保持這種松耦合,客戶會通過一個(gè)工廠發(fā)出請求. 再由工廠創(chuàng)建所請求的產(chǎn)品.也可以換種方式考慮, 利用工廠方法模式, 請求者只發(fā)出請求, 而不具體創(chuàng)建產(chǎn)品.
工廠的工作
先建立一個(gè)工廠的接口
Factory.php
<?php abstract class Factory { //抽象的創(chuàng)建對象的方法 protected abstract function createProduct(); //該方法調(diào)用createProduct方法返回一個(gè)產(chǎn)品對象. public function start() { return $this->createProduct(); } }
start
方法返回一個(gè)產(chǎn)品,該方法調(diào)用createProduct
方法完成產(chǎn)生產(chǎn)品的操作.所以createProduct的具體實(shí)現(xiàn)要構(gòu)建并返回一個(gè)按Product接口實(shí)現(xiàn)的產(chǎn)品對象.
比如產(chǎn)品都有一個(gè)共同的方法getProperties()
, 以下是對應(yīng)Product接口
Product.php
<?php //產(chǎn)品接口 interface Product { public function getProperties(); }
接著, 我們要建立兩個(gè)工廠,文本工廠TextFactory和圖像工廠phptoFactory
TextFactory.php
<?php include_once('Factory.php'); include_once('TextProduct.php'); class TextFactory extends Factory { protected function createProduct() { $product = new TextProduct(); return $product->getProperties(); } }
PhotoFactory.php
<?php include_once('Factory.php'); include_once('PhotoProduct.php'); class PhotoFactory extends Factory { protected function createProduct() { $product = new PhotoProduct(); return $product->getProperties(); } }
可以看到,在工廠方法的實(shí)現(xiàn)中, getProperties方法引入了多態(tài)(polymorphism), 將用這個(gè)方法返回"文本"或"圖像". 同一個(gè)getProperties()
有多個(gè)(poly)不同的形態(tài)(morphs), 這就是多態(tài).在這種情況下, 其中一種形式返回文本, 而另一種返回圖像.
可以在properties這個(gè)實(shí)現(xiàn)中放入你想要的任何東西,工廠方法設(shè)計(jì)將會創(chuàng)建這個(gè)對象, 并把他返回給Client使用.
下面的是兩個(gè)產(chǎn)品的實(shí)現(xiàn)
TextProduct.php
<?php include_once('Product.php'); class TextProduct implements Product { public function getProperties() { return "這里是文本產(chǎn)品"; } }
PhotoProduct.php
<?php include_once('Product.php'); class PhotoProduct implements Product { //這是產(chǎn)品具有的方法 public function getProperties() { return "這里是圖像產(chǎn)品"; } }
這兩個(gè)產(chǎn)品實(shí)現(xiàn)了Product接口中的抽象方法getProperties()
,
客戶(Client)
我們并不希望客戶直接做出產(chǎn)品請求.實(shí)際上, 我們希望客戶通過Factory工廠接口做出請求.這樣一來,如果以后我們增加了產(chǎn)品或者工廠, 客戶可以做同樣的請求來得到更多類型的產(chǎn)品 , 而不會破壞這個(gè)應(yīng)用:
Client.php
<?php include_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();
運(yùn)行Client.php, 得到下面的結(jié)果
這里是圖像產(chǎn)品
這里是文本產(chǎn)品
注意: Client對象并沒有向產(chǎn)品直接做出請求, 而是通過工廠來請求. 重要的是, 客戶并不實(shí)現(xiàn)產(chǎn)品特性, 而留給產(chǎn)品實(shí)現(xiàn)來體現(xiàn).
調(diào)整產(chǎn)品
設(shè)計(jì)模式的真正價(jià)值并不是提高操作的速度, 而是加快開發(fā)的速度.
如果現(xiàn)在需求變化了, 需要對圖像產(chǎn)品做出修改, 只需要修改相應(yīng)的產(chǎn)品PhotoProduct的getProperties方法即可
對象的改變看起來很簡單 不過Product的getProperties()
方法仍保持相同的接口,請求工廠返回一個(gè)屬性對象
增加新產(chǎn)品和參數(shù)化請求
問題來了,如果要增加更多的圖像和文本說明, 有沒有必要每次增加一個(gè)新的區(qū)域就增加一個(gè)新的具體的工廠類?這意味著要為每個(gè)新區(qū)域增加一個(gè)新工廠和產(chǎn)品.于是,我們引進(jìn)了參數(shù)化工廠設(shè)計(jì)模式
參數(shù)化工廠設(shè)計(jì)模式和一般的工廠設(shè)計(jì)模式的主要區(qū)別之一是客戶包含工廠和產(chǎn)品的引用. 在參數(shù)化請求中, Client類必須指定產(chǎn)品, 而不是產(chǎn)品工廠. createProduct()
操作中的參數(shù)是由客戶傳入一個(gè)產(chǎn)品; 所以客戶必須指出它想要的具體產(chǎn)品. 不過, 這個(gè)請求仍然是通過工廠接口Factory發(fā)出的. 所以, 盡管客戶包含一個(gè)產(chǎn)品引用, 但通過Factory, 客戶仍然與產(chǎn)品分離.
一個(gè)工廠多個(gè)產(chǎn)品(參數(shù)化工廠方法)
對于大多數(shù)請求, 參數(shù)化工廠方法更為簡單, 因?yàn)榭蛻糁恍枰幚硪粋€(gè)具體工廠.工廠方法操作有一個(gè)參數(shù),指示需要創(chuàng)建的產(chǎn)品.而在原來的設(shè)計(jì)中, 每個(gè)產(chǎn)品都有自己的工廠, 不需要另個(gè)傳遞參數(shù); 產(chǎn)品實(shí)現(xiàn)依賴于各個(gè)產(chǎn)品特定的工廠.
新工廠接口
Factory.php
<?php abstract class Factory { //抽象的創(chuàng)建對象的方法 protected abstract function createProduct(Product $product); //該方法由factoryMethod方法返回一個(gè)產(chǎn)品對象. public function start($product) { return $this->createProduct($product); } }
在這個(gè)新的Factory接口中可以看到, create()
和start()
都需要一個(gè)參數(shù),指定一個(gè)Product對象, 而不是Product接口的一個(gè)特定實(shí)現(xiàn), 所以可以接受任何Product的具體實(shí)例.
工廠具體實(shí)現(xiàn)
具體的創(chuàng)建者類CommonFactory實(shí)現(xiàn)了createProduct()
,如下
CommonFactory.php
<?php include_once('Factory.php'); include_once('Product.php'); class CommonFactory extends Factory { protected function createProduct(Product $product) { return $product->getProperties(); } }
這個(gè)類調(diào)用Product的方法getProperties將產(chǎn)品返回給客戶.
新產(chǎn)品
具體產(chǎn)品的變化并不會改變原來的Product接口,還是原來的代碼
<?php //產(chǎn)品接口 interface Product { public function getProperties(); }
例如, 現(xiàn)在有一個(gè)鋼筆產(chǎn)品PenProduct
PenProduct.php
<?php include_once('Product.php'); class PenProduct implements Product { public function getProperties() { return "鋼筆產(chǎn)品"; } }
客戶Clent(有參數(shù))
<?php include_once('CommonFactory.php'); include_once('PenProduct.php'); class Client { public function __construct() { $commonFactory = new CommonFactory(); echo $commonFactory->start(new PenProduct()); } } $worker = new Client();
運(yùn)行后輸出
鋼筆產(chǎn)品
以上是“PHP設(shè)計(jì)模式之工廠模式怎么用”這篇文章的所有內(nèi)容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內(nèi)容對大家有所幫助,如果還想學(xué)習(xí)更多知識,歡迎關(guān)注億速云行業(yè)資訊頻道!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。