淺談PHP中的工廠方法模式

青灯夜游
發布: 2023-04-10 08:34:02
轉載
2513 人瀏覽過

本篇文章帶大家來了解PHP設計模式中的工廠方法模式。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有幫助。

淺談PHP中的工廠方法模式

上回說到,簡單工廠不屬於GoF的二十三種設計模式,這回可就來真傢伙了,大名頂的工廠方法模式前來報道!

相關推薦:《淺談PHP中的簡單工廠模式

GoF類別圖解釋

工廠方法模式比較簡單工廠來說,最核心的一點,其實就是將實作延後到子類別。怎麼理解呢?我們可以將上回的簡單工廠當作父類,然後有一堆子類別去繼承它。 createProduct()這個方法在父類別中也變成一個抽象方法。然後所有的子類別去實作這個方法,不再需要用switch去判斷,子類別直接回傳一個實例化的物件即可。

GoF定義:定義一個用於建立物件的接口,讓子類別決定實例化哪一個類別。 Factory Method使一個類別的實例化延遲到其子類別。

GoF類別圖:

淺談PHP中的工廠方法模式

  • #類別圖中的Product為產品
  • 類別圖中的Creator為創建者
  • 創建者父類別有一個抽象的FactoryMethod()工廠方法
  • 所有創建者子類別需要實作這個工廠方法,並傳回對應的具體產品
  • 創建者父類別可以有一個AnOperation()操作方法,直接回傳product,可以使用FactoryMethod()去返回,這樣外部只需要統一呼叫AnOperation()

#程式碼實作

首先是商品相關的介面和實作類,和簡單工廠的類似:

// 商品接口
interface Product{
    function show() : void;
}

// 商品实现类A
class ConcreteProductA implements Product{
    public function show() : void{
        echo "I'm A.\n";
    }
}
登入後複製

接下來是創建者的抽象和實作類別:

// 创建者抽象类
abstract class Creator{

    // 抽象工厂方法
    abstract protected function FactoryMethod() : Product;

    // 操作方法
    public function AnOperation() : Product{
        return $this->FactoryMethod();
    }
}

// 创建者实现类A
class ConcreteCreatorA extends Creator{
    // 实现操作方法
    protected function FactoryMethod() : Product{
        return new ConcreteProductA();
    }
}
登入後複製

這裡和簡單工廠就有了本質的差別,我們去掉了噁心的switch,讓每個具體的實作類別來進行商品物件的建立。沒錯,單一和封閉,每個單獨的創建者子類別只在工廠方法中和一個商品有耦合,有沒有其他商品和其他的工廠來跟客戶合作過這個子類別完全不知道。

同樣還是拿手機來比喻:我是一個賣手機的批發商(客戶Client,業務方),我需要一批手機(產品ProductA),於是我去讓富X康(工廠Creator)來幫我生產。我跟富士康說明了需求,富士康說好的,讓我的衡陽工廠(ConcreteCreatorA)來搞定,不需要總廠上,你這小單子,灑灑水啦。然後過了一陣我又需要另一種型號的手機(產品ProductB),富士康看了看後又讓鄭州富士康(ConcreteCreatorB)來幫我生產。反正不管怎麼樣,他們總是給了我對應的手機。而且鄭州工廠也不知道衡陽工廠生產過什麼或有沒有跟我合作過,這一切只有我和總工廠知道。

完整程式碼:工廠方法模式

https://github.com/zhangyue0503/designpatterns-php/blob/master/02.factory/source/factory. php

實例

場景:光說不練假把式,把上回的簡訊發送改造改造,我們依然還是使用上回的那幾個簡訊發送商。畢竟大家已經很熟悉了嘛,不過以後要更換也說不定,商場如戰場,大家還是利益為先。這樣的話,我們透過工廠方法模式來進行解耦,就可以方便的添加修改短信提供商咯。

簡訊發送類別圖

淺談PHP中的工廠方法模式

#程式碼實作

<?php

interface Message {
    public function send(string $msg);
}

class AliYunMessage implements Message{
    public function send(string $msg){
        // 调用接口,发送短信
        // xxxxx
        return &#39;阿里云短信(原阿里大鱼)发送成功!短信内容:&#39; . $msg;
    }
}

class BaiduYunMessage implements Message{
    public function send(string $msg){
        // 调用接口,发送短信
        // xxxxx
        return &#39;百度SMS短信发送成功!短信内容:&#39; . $msg;
    }
}

class JiguangMessage implements Message{
    public function send(string $msg){
        // 调用接口,发送短信
        // xxxxx
        return &#39;极光短信发送成功!短信内容:&#39; . $msg;
    }
}


abstract class MessageFactory{
    abstract protected function factoryMethod();
    public function getMessage(){
        return $this->factoryMethod();
    }
}

class AliYunFactory extends MessageFactory{
    protected function factoryMethod(){
        return new AliYunMessage();
    }
}

class BaiduYunFactory extends MessageFactory{
    protected function factoryMethod(){
        return new BaiduYunMessage();
    }
}

class JiguangFactory extends MessageFactory{
    protected function factoryMethod(){
        return new JiguangMessage();
    }
}

// 当前业务需要使用百度云
$factory = new BaiduYunFactory();
$message = $factory->getMessage();
echo $message->send(&#39;您有新的短消息,请查收&#39;);
登入後複製

完整原始碼:簡訊發送工廠方法

https://github.com/zhangyue0503/designpatterns-php/blob/master/02.factory/source/factory-message.php

#說明

  • 和類別圖完全一致,基本上不需要什麼說明了吧,注意工廠方法模式的特點,實現推遲到了子類別! !
  • 業務呼叫的時候需要耦合一個Factory子類別。確實是這樣,如果你想一個統一的出口來調用,請在外面加一層簡單工廠就好啦,這就當成一道思考題吧
  • 不拘泥於目前的形式,可以不用抽象類,直接用一個介面來定義工廠方法,摒棄掉getMessage()方法,外部直接呼叫公開的模板方法(factoryMethod)即可

推薦學習:《PHP視訊教學

以上是淺談PHP中的工廠方法模式的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:juejin.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!