關於設計模式這一塊,我的以爲仍是挺重要的。由於這個關乎到代碼的優雅程度。php
今天不講設計模式六大原則,就單純的來講說我對工廠模式的理解,用最通俗易懂的天然語言,講述一下工廠模式的原理。設計模式
定義學習
什麼是工廠模式?就是一種建立型的設計模式。這麼說可能有些晦澀,用通俗易懂的話來講,就是按照一種相似於工廠生產商品的方式來對類進行實例化,而不是用到了就new一個。spa
簡單工廠模式設計
如今有一個客戶,肚子餓了,想吃方便麪。他如今腦子裏這有一個念頭:快點吃到方便麪,他根本就不想了解方便麪究竟是怎麼生產出來的(客戶端與實現的解耦)。這個時候若是有一個賣方便麪的小店(工廠)就行了,客戶只須要看一下店裏有哪些方便麪。而後挑選一包就行了。code
優勢:對象
白話:客戶不須要知道怎麼生產方便麪,就能夠吃到想要的方便麪,甚至能挑選到本身想要的那個牌子的方便麪。blog
書面:客戶端和具體實現的解耦。接口
缺點:開發
白話:這個小店爲了應對愈來愈多的客戶需求,進貨的時候進了100多種品牌的方便麪,味道各不同,描述七老比較困難。吃的方法也不同,有一些是水煮的,有一些是幹吃的,有一些是幹拌的。所以老闆本身也常常記錯,更別說客戶問的時候聽得一頭霧水了。客戶挑了半天,可能並不能挑到本身心滿意足的產品。
書面:隨着數據量的增大,工廠類會變得臃腫。邏輯和實現混雜在一塊兒,使得工廠類的內部構造變得難以理解和維護,很是不利於後期的拓展。對於客戶端來講,須要知道工廠的內部實現,增長了大量的學習成本,增長了客戶端的複雜度。
實現:
首先咱們須要定義一個方便麪的接口,每包方便麪均可以吃:
//noodles.php interface Noodles{ public function eat(); }
而後咱們寫兩個實現類,分別表明康師傅生產的方便麪,和統一輩子產的方便麪:
//kangNoodles.php class KangNoodles implements Noodles{ public function eat(){ echo '吃一包美味的康師傅紅燒牛肉麪'; } } //Tongyi.php class TongyiNoodles implements Noodles{ public function eat(){ echo '吃一包美味的統一紅燒牛肉麪'; } }
而後咱們生成一個簡單工廠:
//NoodlesFactory.php class NoodlesFactory{ public function createNoodles($brand){ switch($brand){ case 'kang': return new KangNoodles(); case 'tongyi': return new TongyiNoodles(); } } }
生成客戶端:
//SimpleFactoryDemo.php class SimpleFactoryDemo{ public function setNoodles($brand){ $noodles = (new NoodlesFactory())->createNoodles($brand); $noodles->eat(); } }
工廠模式
仍是上述場景,客戶肚子餓了想吃方便麪。如今咱們創建一個康師傅工廠,專門生產(售賣)康師傅紅燒牛肉麪,再創建一個生產(售賣)統一紅燒牛肉麪的工廠,等等,在理想的條件下,咱們甚至能夠創建起100個品牌的方便麪加工工廠,客戶想吃哪個牌子,直接去對應的工廠(商店)進行購買就好了。
優勢:
相對於簡單工廠模式,工廠模式的每個工廠都作本身的事,避免創建起一個龐大而又臃腫的工廠。有利於代碼的擴展和維護。
缺點:
每增長一個產品,相應的也要增長一個子工廠,加大了額外的開發量(我的以爲這一點能夠接受,不算什麼太大的缺點)
實現:
首先咱們須要定義一個方便麪的接口
//noodles.php interface Noodles{ public function eat(); }
而後咱們寫兩個實現類,分別表明生產康師傅生產的方便麪,和統一輩子產的方便麪這種商品:
//kangNoodles.php class KangNoodles implements Noodles{ public function eat(){ echo '吃一包美味的康師傅紅燒牛肉麪'; } } //Tongyi.php class TongyiNoodles implements Noodles{ public function eat(){ echo '吃一包美味的統一紅燒牛肉麪'; } }
而後,生成一個工廠接口:
//NoodlesFactory.php interface NoodlesFactory{ public function createNoodles(); }
咱們生成兩個對應的工廠:
//KangNoodlesFactory.php class KangNoodlesFactory implements NoodlesFactory{ public function createNoodles(){ return new KangNoodles(); } } //TongyiNoodlesFactory.php class TongyiNoodlesFactory implements NoodlesFactory{ public function createNoodles(){ return new TongyiNoodles(); } }
生成客戶端:
//FactoryDemo.php class FactoryDemo{ public function kangFunc(){ $noodles = (new KangNoodlesFactory())->createNoodles(); $noodles->eat(); } public function TongyiFunc(){ $noodles = (new TongyiNoodlesFactory())->createNoodles(); $noodles->eat(); } }
抽象工廠模式
仍是上述場景,隨着物質條件的提高,客戶提出,要在吃泡麪的時候加一分榨菜,造成一個套餐。這個時候怎麼辦?
咱們能夠把泡麪和榨菜想象成一個「套餐」,統一交給一家工廠(商店)去幫忙搞定。市場上因而新推出一條這樣的套餐:泡麪——榨菜。因而各個廠家紛紛效仿,推出自家工廠的「套餐」。客戶只須要到對應的工廠直接下單套餐就好了,無需其餘操做。
優勢:
擁有工廠模式的優勢。
擁有產品族的概念,這一系列的產品源於同一廠家,易於管理約束。保證客戶只使用同一家工廠的產品。
一個具體的工廠實現表明的是一個產品族,切換產品族只須要切換一下具體工廠
缺點:
若是要新增長一個產品,好比說套餐中要加入一款飲料。那麼全部的工廠都要去遵循這個規定,去研發出一款自家的飲料,比較麻煩。
實現:
首先咱們須要定義一個方便麪的接口
//noodles.php interface Noodles{ public function eat(); }
而後咱們寫兩個實現類,分別表明生產康師傅生產的方便麪,和統一輩子產的方便麪這種商品:
//kangNoodles.php class KangNoodles implements Noodles{ public function eat(){ echo '吃一包美味的康師傅紅燒牛肉麪'; } } //Tongyi.php class TongyiNoodles implements Noodles{ public function eat(){ echo '吃一包美味的統一紅燒牛肉麪'; } }
咱們再寫一個榨菜的接口:
//Mustard.php interface Mustard{ public functioneat(); }
再寫兩個榨菜的實現類:
//kangMusterd.php class kangMusterd implements Musterd{ public function eat(){ echo '吃一包美味的康師傅榨菜'; } } //Tongyi.php class TongyiMusterd implements Musterd{ public function eat(){ echo '吃一包美味的統一榨菜'; } }
寫一個抽象工廠,包含多個產品:
//AbstractFactory.php abstract AbstractFactory(){ abstract public function createNoodle(); abstract public function createMusterd(); }
生成兩個工廠類:
//KangFactory.php class KangFactory extends AbstractFactory{ public function createNoodles(){ return new KangNoodles(); } public function createMusterd(){ return new KangMusterd(); } } //TongyiFactory.php class TongyiFactory extends AbstractFactory{ public function createNoodles(){ return new TongyiNoodles(); } public function createMusterd(){ return new TongyiMusterd(); } }
客戶端:
//AbstractFactoryDemo.php class AbstractFactoryDemo{ public function eatKangTaocan(){ $kangFactory = new KangFactory(); $noodles = $kangFactory->createNoodles(); $musterd = $kangFactory->createMusterd(); $noodles->eat(); $musterd->eat(); } public function eatTongyiTaocan(){ $TongyiFactory = new TongyiFactory(); $noodles = $TongyiFactory->createNoodles(); $musterd = $TongyiFactory->createMusterd(); $noodles->eat(); $musterd->eat(); } }
總結:
後兩種工廠模式,其實就是把建立對象的那個行爲抽象出來了,作到了低耦合。