PHP 工廠模式

(一個創造者、一個產品,將類的實例化和對象的使用分離開,這就是工廠模式的思想)
 
工廠模式的確是讓初學者比較費解的模式。
首先它有簡單工廠和抽象工廠之分。但真正算得上設計模式的,是抽象工廠。而簡單工廠說實在的僅僅是比較天然的再封裝。因此不少教科書會顯擺本身的內涵大幅度的介紹抽象工廠,而有意無心的忽略了簡單工廠。
實際的狀況又正好相反,簡單工廠幾乎每一個人都會用得上,抽象工廠大部分人一生都用不上一次。
下面回答你的問題:簡單工廠封裝了new到底有啥好處?
在實際的項目中,在你通往架構師的道路上,你要培養出一種感受:要new一個實體對象是件很謹慎的事情(不是指值對象),不要隨便new。最好不要本身new,讓別人去new,傳給你去調用。這樣new錯了也是別人的事,換而言之你的模塊是好質量的,禁得起推敲的。那麼都不肯意去new,誰去new?讓專門的一個工廠去new。請注意:這僅僅是解決new的方式之一,此外還要反射啊等等。那你必需要等到真正接觸大型項目纔能有體味的。


做者:餘葉
連接: https://www.zhihu.com/question/24843188/answer/49197026
來源:知乎
著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。
 
 

1.隱藏具體類名,不少類隱藏得很深的,並且可能會在後續版本換掉
2.避免你辛苦的準備構造方法的參數
3.這個工廠類能夠被配置成其它類
4.這個工廠對象能夠被傳遞php

最後來句重要的
new XXX其實也是一種硬編碼!!!
 
舉一個例子,在遊戲中,咱們要一個戰士配裝備,首先咱們須要配一把槍械(槍械有不少,步槍,狙擊槍等,使用問題 1 進行抽象),可是配了槍械以後,咱們還須要配子彈啊(繼續使用問題 1 的方法進行抽象),好了,如今能夠抽象出 2 層的工廠類了,針對如今的狀況咱們是否是可讓一個工廠既生產槍械,又生產子彈呢? 這就是 抽象工廠模式。簡單來講, 能夠把有一些有聯繫或者相近的產品,放到一個工廠去生產,沒有必要單獨再開一個工廠了


概念

工廠模式是咱們最經常使用的實例化對象模式,是用工廠方法代替new操做的一種模式。html

使用工廠模式的好處是,若是你想要更改所實例化的類名等,則只需更改該工廠方法內容便可,不需逐一尋找代碼中具體實例化的地方(new處)修改了。爲系統結構提供靈活的動態擴展機制,減小了耦合。vim

根據抽象程度的不一樣,PHP工廠模式分爲三種:設計模式

  1. 簡單工廠模式架構

  2. 工廠方法模式測試

  3. 抽象工廠模式編碼

講解

簡單工廠模式

簡單工廠模式又稱靜態工廠方法模式,之因此能夠這麼說,是由於簡單工廠模式是經過一個靜態方法來建立對象的。spa

代碼示例:設計

<?php header('Content-Type:text/html;charset=utf-8'); /** *簡單工廠模式(靜態工廠方法模式) */ /** * Interface people 人類 */ interface people { public function say(); } /** * Class man 繼承people的男人類 */ class man implements people { // 具體實現people的say方法 public function say() { echo '我是男人<br>'; } } /** * Class women 繼承people的女人類 */ class women implements people { // 具體實現people的say方法 public function say() { echo '我是女人<br>'; } } /** * Class SimpleFactoty 工廠類 */ class SimpleFactoty { // 簡單工廠裏的靜態方法-用於建立男人對象 static function createMan() { return new man(); } // 簡單工廠裏的靜態方法-用於建立女人對象 static function createWomen() { return new women(); } } /** * 具體調用 */ $man = SimpleFactoty::createMan(); $man->say(); $woman = SimpleFactoty::createWomen(); $woman->say(); 

運行結果:代理

我是男人
我是女人

工廠方法模式

定義一個用於建立對象的接口,讓子類決定哪一個類實例化。 他能夠解決簡單工廠模式中的封閉開放原則問題。

看代碼:

<?php header('Content-type:text/html;charset=utf-8'); /* *工廠方法模式 */ /** * Interface people 人類 */ interface people { public function say(); } /** * Class man 繼承people的男人類 */ class man implements people { // 實現people的say方法 function say() { echo '我是男人-hi<br>'; } } /** * Class women 繼承people的女人類 */ class women implements people { // 實現people的say方法 function say() { echo '我是女人-hi<br>'; } } /** * Interface createPeople 建立人物類 * 注意:與上面簡單工廠模式對比。這裏本質區別在於,此處是將對象的建立抽象成一個接口。 */ interface createPeople { public function create(); } /** * Class FactoryMan 繼承createPeople的工廠類-用於實例化男人類 */ class FactoryMan implements createPeople { // 建立男人對象(實例化男人類) public function create() { return new man(); } } /** * Class FactoryMan 繼承createPeople的工廠類-用於實例化女人類 */ class FactoryWomen implements createPeople { // 建立女人對象(實例化女人類) function create() { return new women(); } } /** * Class Client 操做具體類 */ class Client { // 具體生產對象並執行對象方法測試 public function test() { $factory = new FactoryMan(); $man = $factory->create(); $man->say(); $factory = new FactoryWomen(); $man = $factory->create(); $man->say(); } } // 執行 $demo = new Client; $demo->test();

看結果:

我是男人-hi 我是女人-hi

抽象工廠模式

提供一個建立一系列相關或相互依賴對象的接口。

注意:這裏和工廠方法的區別是:一系列(多個),而工廠方法只有一個。

代碼:

<?php header('Content-type:text/html;charset=utf-8'); /* * 抽象工廠模式 */ /** * Interface people 人類 */ interface people { public function say(); } /** * Class OneMan 第一個男人類-繼承people */ class OneMan implements people { // 實現people的say方法 public function say() { echo '男1:我喜歡你<br>'; } } /** * Class TwoMan 第二個男人類-繼承people */ class TwoMan implements people{ // 實現people的say方法 public function say() { echo '男2:我看上你了<br>'; } } /** * Class OneWomen 第一個女人類-繼承people */ class OneWomen implements people { // 實現people的say方法 public function say() { echo '女1:我不喜歡你<br>'; } } /** * Class TwoWomen 第二個女人類-繼承people */ class TwoWomen implements people { // 實現people的say方法 public function say() { echo '女2:滾一邊玩去<br>'; } } /** * Interface createPeople 建立對象類 * 注意:這裏將對象的建立抽象成了一個接口。 */ interface createPeople { // 建立第一個 public function createOne(); // 建立第二個 public function createTwo(); } /** * Class FactoryMan 用於建立男人對象的工廠類-繼承createPeople */ class FactoryMan implements createPeople { // 建立第一個男人 public function createOne() { return new OneMan(); } // 建立第二個男人 public function createTwo() { return new TwoMan(); } } /** * Class FactoryWomen 用於建立女人對象的工廠類-繼承createPeople */ class FactoryWomen implements createPeople { // 建立第一個女人 public function createOne() { return new OneWomen(); } // 建立第二個女人 public function createTwo() { return new TwoWomen(); } } /** * Class Client 執行測試類 */ class Client { // 具體生成對象和執行方法 public function test() { // 男人 $factory = new FactoryMan(); $man = $factory->createOne(); $man->say(); $man = $factory->createTwo(); $man->say(); // 女人 $factory = new FactoryWomen(); $man = $factory->createOne(); $man->say(); $man = $factory->createTwo(); $man->say(); } } // 執行 $demo = new Client; $demo->test();

結果:

1:我喜歡你 男2:我看上你了 女1:我不喜歡你 女2:滾一邊玩去

總結

區別

  1. 簡單工廠模式(靜態方法工廠模式) : 用來生產同一等級結構中的任意產品。(不能增長新的產品)

  2. 工廠模式 :用來生產同一等級結構中的固定產品。(支持增長任意產品)

  3. 抽象工廠 :用來生產不一樣產品種類的所有產品。(不能增長新的產品,支持增長產品種類)

適用範圍

簡單工廠模式:

工廠類負責建立的對象較少,操做時只需知道傳入工廠類的參數便可,對於如何建立對象過程不用關心。

工廠方法模式:

知足如下條件時,能夠考慮使用工廠模式方法

  1. 當一個類不知道它所必須建立對象的類時

  2. 一個類但願由子類來指定它所建立的對象時

  3. 當類將建立對象的職責委託給多個幫助子類中得某一個,而且你但願將哪個幫助子類是代理者這一信息局部化的時

抽象工廠模式:

知足如下條件時,能夠考慮使用抽象工廠模式

  1. 系統不依賴於產品類實例如何被建立,組合和表達的細節。

  2. 系統的產品有多於一個的產品族,而系統只消費其中某一族的產品

  3. 同屬於同一個產品族是在一塊兒使用的。這一約束必須在系統的設計中體現出來。

  4. 系統提供一個產品類的庫,全部產品以一樣的接口出現,從而使客戶端不依賴於實現。

以上幾種,歸根結底,都是將重複的東西提取出來,以方便總體解耦和複用,修改時方便。可根據具體需求而選擇使用。

相關文章
相關標籤/搜索