工厂主要有三种模式:抽象工厂、简单工厂、工厂方法,本文所说的是简单工厂模式,其他两种模式也是大同小异。

应用场景

项目中,在不确定有多少种处理操作时,可以用简单工厂模式。

比如:

数据库的连接,可能是mysql,也可能是oracle

支付方式的选择,可能是支付宝,也可能是银联支付,也可能后期会加别的支付方式。

示例代码

这里以支付渠道选择为例。

部分目录结构

├── app
│   └── payment
│       ├── Factory.php
│       └── handle
│           ├── Alipay.php
│           ├── PayInterface.php
│           └── Unionpay.php

app/payment/Factory.php为工厂类

<?php

namespace app\payment;

use app\payment\handle\Alipay;
use app\payment\handle\Unionpay;

/**
 * 支付渠道工厂
 * Class Factory
 * @package app\payment
 */
class Factory
{
    /**
     * 创建支付渠道实例
     * @param $type
     * @return Alipay|Unionpay
     * @throws \ErrorException
     */
    public function create($type)
    {
        switch ($type) {
            // 银联支付
            case 'unionpay':
                return new Unionpay();
            // 支付宝
            case 'alipay':
                return new Alipay();
            default:
                throw new \ErrorException('支付渠道不存在');
        }
    }
}

app/payment/handle/PayInterface.php为每个支付渠道必须完成的统一接口

<?php

namespace app\payment\handle;

/**
 * 支付渠道统一接口
 * Interface PayInterface
 * @package app\payment\handle
 */
interface PayInterface
{
    /**
     * 设置支付参数
     * @param array $data
     * @return mixed
     */
    public function setParams(array $data);

    /**
     * 发起支付
     * @return mixed
     */
    public function send();

    /**
     * 检查签名
     * @param array $data
     * @return mixed
     */
    public function check(array $data);
}

app/payment/handle/Unionpay.php为银联支付实例

这里仅做演示,未实现具体方法

<?php

namespace app\payment\handle;

/**
 * 银联支付
 * Class Unionpay
 * @package app\payment\handle
 */
class Unionpay implements PayInterface
{
    public function setParams(array $data)
    {
        // TODO: Implement setParams() method.
    }

    public function send()
    {
        // TODO: Implement execute() method.
    }

    public function check(array $data)
    {
        // TODO: Implement check() method.
    }
}

app/payment/handle/Alipay.php为支付宝实例

这里仅做演示,未实现具体方法

<?php

namespace app\payment\handle;

/**
 * 支付宝支付
 * Class Alipay
 * @package app\payment\handle
 */
class Alipay implements PayInterface
{
    public function setParams(array $data)
    {
        // TODO: Implement setParams() method.
    }

    public function send()
    {
        // TODO: Implement send() method.
    }

    public function check(array $data)
    {
        // TODO: Implement check() method.
    }
}

使用工厂创建支付实例,发起支付:

<?php

use app\payment\Factory;

$factory = new Factory();
// 创建支付渠道
$payment = $factory->create('alipay');
// 设置支付参数
$payment->setParams([
    [
        'subject' => '测试',
        'out_trade_no' => '56AF4DSA4DSF5A64D5ASF',
        'total_amount' => '0.01',
    ]
]);
// 发起支付
$payment->send();

这样就实现了一个简单工厂模式,后期如果要加其他支付渠道, 只需要添加一个支付实例实现app/payment/handle/PayInterface.php接口的方法即可, 调用的方法不变,这样即添加了新功能,又不改变原有代码逻辑。