PHP設計模式之簡單工廠模式

先從簡單工廠入門,不論是面試仍是被他人面試,在問到設計模式的時候,大多數人都會提到工廠模式。毫無疑問,工廠相關的幾種模式在設計模式中是最出名的也是應用比較普遍的一種模式。在GoF設計模式中也都是屬於建立型的模式。php

可是,可以說明白簡單工廠工廠模式抽象工廠模式這三種模式的人還真能讓面試官另眼相看。這裏有個前提,是你真的能說明白,大部分人,包括在深刻研究設計模式以前,我也沒辦法說清楚。不論是我去面試,仍是面試其別人。當我面試別人的時候,能講個大概也就差很少了。而我去面試的時候,也就是相似的講個大概。經歷很多挫折以後纔有了想深刻的研究研究設計模式的想法,因而便會產生這一系列的文章。從這篇簡單工廠開始,咱們一塊兒再次深刻的對設計模式進行學習。git

固然,這裏用的是PHP。

解釋

簡單工廠,也稱靜態工廠,不屬於GoF23種設計模式。可是能夠說是全部的設計模式中你們可能最容易理解,也可能在你的代碼中早就已經用過不知道多少次的一種設計模式了。咱們先從一個最最簡單的代碼段來看。github

// Factory
class Factory
{
    public static function createProduct(string $type) : Product
    {
        $product = null;
        switch ($type) {
            case 'A':
                $product = new ProductA();
                break;
            case 'B':
                $product = new ProductB();
                break;
        }
        return $product;
    }
}

沒錯,核心點就是中間那段簡單的switch代碼,咱們在返回值類型中固定爲Product接口的實現。面試

在這段代碼中,使用了PHP新特性,參數類型返回值類型設計模式

產品接口和產品實現微信

// Products
interface Product
{
    public function show();
}

class ProductA implements Product
{
    public function show()
    {
        echo 'Show ProductA';
    }
}

class ProductB implements Product
{
    public function show()
    {
        echo 'Show ProductB';
    }
}

最後客戶端的使用就很簡單了架構

// Client
$productA = Factory::createProduct('A');
$productB = Factory::createProduct('B');
$productA->show();
$productB->show();

從以上代碼能夠看出,其實這裏就是一個工廠類根據咱們傳入的字符串或者其餘你本身定義的標識符,來返回對應的產品(Product對象)。學習

形象化一點的比喻:我是一個賣手機的批發商(客戶Client,業務方),我須要一批手機(產品Product),因而我去讓富士康(工廠Factory)來幫我生產。我下了訂單($type變量)指明型號,而後富士康就給我對應型號的手機,而後我就繼續個人工做了,和富士康的合做還真是挺愉快的。阿里雲

這裏比較規範的寫法多是全部產品都會去實現一個統一的接口,而後客戶端只知道接口的方法統一調用便可。不規範的話也能夠不使用接口,返回各類不一樣的對象,相似於外觀(Facade)模式進行統一的門面管理。設計

簡單工廠-講解

源碼地址:簡單工廠基礎類圖實現

實例

場景:短信發送功能模塊。如今咱們使用了三個商家的,分別是阿里雲、蝶信、極光的短信服務,在不一樣業務中可能使用不一樣的短信發送商,使用簡單工廠能夠方便的完成這個需求。

類圖

簡單工廠-消息發送

代碼

<?php

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

class AliYunMessage implements Message{
    public function send(string $msg){
        // 調用接口,發送短信
        // xxxxx
        return '阿里雲短信(原阿里大魚)發送成功!短信內容:' . $msg;
    }
}

class BaiduYunMessage implements Message{
    public function send(string $msg){
        // 調用接口,發送短信
        // xxxxx
        return '百度SMS短信發送成功!短信內容:' . $msg;
    }
}

class JiguangMessage implements Message{
    public function send(string $msg){
        // 調用接口,發送短信
        // xxxxx
        return '極光短信發送成功!短信內容:' . $msg;
    }
}

Class MessageFactory {
    public static function createFactory($type){
        switch($type){
            case 'Ali':
                return new AliYunMessage();
            case 'BD':
                return new BaiduYunMessage();
            case 'JG':
                return new JiguangMessage();
            default:
                return null;
        }
    }
}

// 當前業務須要使用極光
$message = MessageFactory::createMessage('Ali');
echo $message->send('您有新的短消息,請查收');

源碼地址:簡單工廠實例-短信發送工廠

說明

  • createMessage必定要使用static?不必定,看本身業務狀況決定,須要常駐的所有static,按需實例化的就new完了再正常->去調用
  • 三個message子類必定須要實現接口?也不必定,php自己就是弱類型語言,能夠不去強制實現,但使用接口更加符合面向對象的規範(請參考多態),簡單工廠自己實際上是對多態的一種表述和應用
  • 當須要增長髮送消息的渠道時,添加新類繼承Message接口,實現send()方法,修改MessageFactory()中createFactory()方法裏的switch
  • 思考上述修改違背了面向對象的什麼原則?(提示:開放XX)
  • 實例中沒有使用返回值類型?自己這也是新語法,對於老版本兼容來講能夠不須要去寫,可是若是公司技術棧已經升級到7以上的話,建議這種設計模式架構類的代碼仍是按照上方解釋中的新特性寫法去書寫,也就是帶上參數類型和返回值類型,更加的符合規範,也更容易理解
  • 實例中傳錯了$type返回NULL怎麼辦?親,實際寫代碼的時候請處理好這個問題喲,返回一個默認的,或者上層捕獲都是不錯的解決方案,固然最好客戶端那邊提早判斷好,沒問題了再進工廠吧

下期看點

工廠方法模式,接着發短信,但這回咱們讓客戶端換個姿式來發*

關注公衆號:【硬核項目經理】獲取最新文章

添加微信/QQ好友:【xiaoyuezigonggong/149844827】免費得PHP、項目管理學習資料

知乎、公衆號、抖音、頭條搜索【硬核項目經理】

B站ID:482780532

相關文章
相關標籤/搜索