日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

PHP設(shè)計(jì)模式之工廠方法模式

 硬核項(xiàng)目經(jīng)理 2021-05-31

PHP設(shè)計(jì)模式之工廠方法模式

上回說(shuō)到,簡(jiǎn)單工廠不屬于GoF的二十三種設(shè)計(jì)模式,這回可就來(lái)真家伙了,大名頂頂?shù)?span style="box-sizing: border-box;font-weight: 600;">工廠方法模式前來(lái)報(bào)道!

GoF類圖解釋

工廠方法模式對(duì)比簡(jiǎn)單工廠來(lái)說(shuō),最核心的一點(diǎn),其實(shí)就是將實(shí)現(xiàn)推遲到子類。怎么理解呢?我們可以將上回的簡(jiǎn)單工廠當(dāng)做父類,然后有一堆子類去繼承它。createProduct()這個(gè)方法在父類中也變成一個(gè)抽象方法。然后所有的子類去實(shí)現(xiàn)這個(gè)方法,不再需要用switch去判斷,子類直接返回一個(gè)實(shí)例化的對(duì)象即可。

GoF定義:定義一個(gè)用于創(chuàng)建對(duì)象的接口,讓子類決定實(shí)例化哪一個(gè)類。Factory Method使一個(gè)類的實(shí)例化推遲到其子類。

GoF類圖

  • 類圖中的Product為產(chǎn)品

  • 類圖中的Creator為創(chuàng)建者

  • 創(chuàng)建者父類有一個(gè)抽象的FactoryMethod()工廠方法

  • 所有創(chuàng)建者子類需要實(shí)現(xiàn)這個(gè)工廠方法,返回對(duì)應(yīng)的具體產(chǎn)品

  • 創(chuàng)建者父類可以有一個(gè)AnOperation()操作方法,直接返回product,可以使用FactoryMethod()去返回,這樣外部只需要統(tǒng)一調(diào)用AnOperation()

代碼實(shí)現(xiàn)

首先是商品相關(guān)的接口和實(shí)現(xiàn)類,和簡(jiǎn)單工廠的類似:

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

// 商品實(shí)現(xiàn)類A
class ConcreteProductA implements Product{
public function show() : void{
echo "I'm A.\n";
}
}

接下來(lái)是創(chuàng)建者的抽象和實(shí)現(xiàn)類:

// 創(chuàng)建者抽象類
abstract class Creator{

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

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

// 創(chuàng)建者實(shí)現(xiàn)類A
class ConcreteCreatorA extends Creator{
// 實(shí)現(xiàn)操作方法
protected function FactoryMethod() : Product{
return new ConcreteProductA();
}
}

這里和簡(jiǎn)單工廠就有了本質(zhì)的區(qū)別,我們?nèi)サ袅藧盒牡膕witch,讓每個(gè)具體的實(shí)現(xiàn)類來(lái)進(jìn)行商品對(duì)象的創(chuàng)建。沒錯(cuò),單一和封閉,每個(gè)單獨(dú)的創(chuàng)建者子類只在工廠方法中和一個(gè)商品有耦合,有沒有其他商品和其他的工廠來(lái)跟客戶合作過(guò)這個(gè)子類完全不知道。

同樣還是拿手機(jī)來(lái)比喻:我是一個(gè)賣手機(jī)的批發(fā)商(客戶Client,業(yè)務(wù)方),我需要一批手機(jī)(產(chǎn)品ProductA),于是我去讓富X康(工廠Creator)來(lái)幫我生產(chǎn)。我跟富士康說(shuō)明了需求,富士康說(shuō)好的,讓我的衡陽(yáng)工廠(ConcreteCreatorA)來(lái)搞定,不需要總廠上,你這小單子,灑灑水啦。然后過(guò)了一陣我又需要另一種型號(hào)的手機(jī)(產(chǎn)品ProductB),富士康看了看后又讓鄭州富士康(ConcreteCreatorB)來(lái)幫我生產(chǎn)。反正不管怎么樣,他們總是給了我對(duì)應(yīng)的手機(jī)。而且鄭州工廠并不知道衡陽(yáng)工廠生產(chǎn)過(guò)什么或者有沒有跟我合作過(guò),這一切只有我和總工廠知道。

完整代碼:工廠方法模式

實(shí)例

場(chǎng)景:光說(shuō)不練假把式,把上回的短信發(fā)送改造改造,我們依然還是使用上回的那幾個(gè)短信發(fā)送商。畢竟大家已經(jīng)很熟悉了嘛,不過(guò)以后要更換也說(shuō)不定,商場(chǎng)如戰(zhàn)場(chǎng),大家還是利益為先。這樣的話,我們通過(guò)工廠方法模式來(lái)進(jìn)行解耦,就可以方便的添加修改短信提供商咯。

短信發(fā)送類圖

代碼實(shí)現(xiàn)


<?php

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

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

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

class JiguangMessage implements Message{
public function send(string $msg){
// 調(diào)用接口,發(fā)送短信
// xxxxx
return '極光短信發(fā)送成功!短信內(nèi)容:' . $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();
}
}

// 當(dāng)前業(yè)務(wù)需要使用百度云
$factory = new BaiduYunFactory();
$message = $factory->getMessage();
echo $message->send('您有新的短消息,請(qǐng)查收');

完整源碼:短信發(fā)送工廠方法

說(shuō)明

  • 和類圖完全一致,基本不需要什么說(shuō)明了吧,注意工廠方法模式的特點(diǎn),實(shí)現(xiàn)推遲到了子類??!

  • 業(yè)務(wù)調(diào)用的時(shí)候需要耦合一個(gè)Factory子類。確實(shí)是這樣,如果你想一個(gè)統(tǒng)一的出口來(lái)調(diào)用,請(qǐng)?jiān)谕饷婕右粚雍?jiǎn)單工廠就好啦,這就當(dāng)成一道思考題吧

  • 不拘泥于目前的形式,可以不用抽象類,直接用一個(gè)接口來(lái)定義工廠方法,摒棄掉getMessage()方法,外部直接調(diào)用公開的模板方法(factoryMethod)即可

下期看點(diǎn)

抽象工廠模式,老大哥即將登場(chǎng)。壓軸的總是最強(qiáng)悍的,讓我們看看老大哥的本事!

github鏈接:https://github.com/zhangyue0503/designpatterns-php/blob/master/02.factory/blog.md

點(diǎn)擊原文鏈接可跳轉(zhuǎn)至github查看

    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多