關于設計模式這一塊,個人覺得還是挺重要的,因為這個關乎到代碼的優雅程度,
今天不講設計模式六大原則,就單純的來說說我對工廠模式的理解,用最通俗易懂的自然語言,講述一下工廠模式的原理,
定義
什么是工廠模式?就是一種創建型的設計模式,這么說可能有些晦澀,用通俗易懂的話來說,就是按照一種類似于工廠生產商品的方式來對類進行實體化,而不是用到了就new一個,
簡單工廠模式
現在有一個客戶,肚子餓了,想吃方便面,他現在腦子里這有一個念頭:快點吃到方便面,他根本就不想了解方便面到底是怎么生產出來的(客戶端與實作的解耦),這個時候如果有一個賣方便面的小店(工廠)就好了,客戶只需要看一下店里有哪些方便面,然后挑選一包就好了,
優點:
白話:客戶不需要知道怎么生產方便面,就可以吃到想要的方便面,甚至能挑選到自己想要的那個牌子的方便面,
書面:客戶端和具體實作的解耦,
缺點:
白話:這個小店為了應對越來越多的客戶需求,進貨的時候進了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(); } }
總結:
后兩種工廠模式,其實就是把創建物件的那個行為抽象出來了,做到了低耦合,
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/225610.html
標籤:設計模式
上一篇:SCI文章寫作攻略—起飛站
下一篇:設計模式之工廠模式
