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

相关文章
相关标签/搜索