上回说到,简单工厂不属于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('您有新的短消息,请查收');
复制代码
完整源码:短信发送工厂方法
说明
抽象工厂模式,老大哥即将登场。压轴的老是最强悍的,让咱们看看老大哥的本事!