設計模式之工廠模式

關於設計模式這一塊,我的以爲仍是挺重要的。由於這個關乎到代碼的優雅程度。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();

    }   
}  

總結:

後兩種工廠模式,其實就是把建立對象的那個行爲抽象出來了,作到了低耦合。

相關文章
相關標籤/搜索