上回說到,簡單工廠不屬於GoF的二十三種設計模式,這回可就來真傢伙了,大名頂頂的工廠方法模式前來報道!php
工廠方法模式對比簡單工廠來講,最核心的一點,其實就是將實現推遲到子類。怎麼理解呢?咱們能夠將上回的簡單工廠當作父類,而後有一堆子類去繼承它。createProduct()這個方法在父類中也變成一個抽象方法。而後全部的子類去實現這個方法,再也不須要用switch去判斷,子類直接返回一個實例化的對象便可。git
GoF定義:定義一個用於建立對象的接口,讓子類決定實例化哪個類。Factory Method使一個類的實例化推遲到其子類。github
GoF類圖設計模式
代碼實現this
首先是商品相關的接口和實現類,和簡單工廠的相似:阿里雲
// 商品接口
interface Product{
function show() : void;
}
// 商品實現類A
class ConcreteProductA implements Product{
public function show() : void{
echo "I'm A.\n";
}
}
複製代碼
接下來是建立者的抽象和實現類:spa
// 建立者抽象類
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)來幫我生產。反正無論怎麼樣,他們老是給了我對應的手機。並且鄭州工廠並不知道衡陽工廠生產過什麼或者有沒有跟我合做過,這一切只有我和總工廠知道。code
完整代碼:工廠方法模式cdn
場景:光說不練假把式,把上回的短信發送改造改造,咱們依然仍是使用上回的那幾個短信發送商。畢竟你們已經很熟悉了嘛,不過之後要更換也說不定,商場如戰場,你們仍是利益爲先。這樣的話,咱們經過工廠方法模式來進行解耦,就能夠方便的添加修改短信提供商咯。
短信發送類圖
代碼實現
<?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;
}
}
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('您有新的短消息,請查收');
複製代碼
完整源碼:短信發送工廠方法
說明
抽象工廠模式,老大哥即將登場。壓軸的老是最強悍的,讓咱們看看老大哥的本事!