PHP简单工厂模式应用

PHP简单工厂模式应用

以前很多设计模式都只是了解并未有实际经验,实习几个月了刚好有在项目总用到一个简单的工厂模式,特此记录下来。

最后将设计模式在Larave中实现 http://extended-design-php.kyle.link

需求

因为项目需要对接很多支付通道,每个通道的操作都非常类似但是又有一些参数的不同,为此我使用了工厂模式将每个支付通道的独立出来。

Code

最主要的就是根据不同的支付方式的回调进行不同的处理

  • 支付回调请求入口
/**
 * 支付回调 [针对不同的通道做不同的处理].
 *
 * @param int $id
 *
 * @return \Illuminate\Http\Response
 */
public function callback(Request $request)
{
    $channel_code = $request->route('channel_code');

    PayChannel::where('code', '=', $channel_code)->firstOrFail();
    $res = PayServices::CheckOrderCallback($request);

    return view('pays.callback');
}
  • Service调用工厂实例
/**
 * 处理回调
 *
 * @param int $id
 *
 * @return /App/Order
 */
public static function CheckOrderCallback($request)
{
    $pay_channle_instance = PayChannelAbsract::GetChannelInstance($request);

    if (!$pay_channle_instance) {
        abort(403,"Channel not exists");
    }

    $res = $pay_channle_instance->onNotify($request);
    return $res;
}
}
  • 工厂模式抽象类和相关方法
<?php

namespace App\Services\PayChannel;

use App\Order;
use Illuminate\Http\Request;

abstract class PayChannelAbsract
{
    abstract public function getPayInfo(Order $order);

    abstract public function onNotify(Request $request);

    abstract public function isPaymentFinished(Order $order);

    /**
     * 支付通道初始化.
     *
     * @return \App\Order
     */
    public function __construct(Request $request)
    {

    }

    /**
     * 支付通道初始化.
     *
     * @return \App\Services\PayChannel\PayChannelAbsract;
     */
    public static function GetChannelInstance(Request $request)
    {
        $channel_code = $request->route('channel_code');

        //  检查通道文件
        self::checkPayInstance($channel_code);

        switch ($channel_code) {
            case 'kuaijiepay':
                return new PayChannelKuaiJie($request);
            default:
                return null;
        }
    }

    private static function checkPayInstance($channel_code)
    {

    }
}

  • 某个工厂类的具体实现方法
<?php

namespace App\Services\PayChannel;

use App\Order;
use Illuminate\Http\Request;

class PayChannelKuaiJie extends PayChannelAbsract
{
    public function getPayInfo(Order $order)
    {
        // TODO: Implement getPayInfo() method.
    }

    public function onNotify(Request $request)
    {
        // TODO: Implement onNotify() method.

        //  查找订单
        $order = Order
            ::where('order_num', '=', $request->input('order_num'))
            ->firstOrFail();
        //  检查订单状态
        if ($this->isPaymentFinished($order)) {
            abort(403,"Order Already Pay Successd");
        } else {
        //  完成订单
            $order->status = Order::FINISH_STATUS;
            $order->save();
        }

        return $order;
    }

    public function isPaymentFinished(Order $order)
    {
        // TODO: Implement isPaymentFinished() method.
        if ($order->status == Order::FINISH_STATUS) {
            return true;
        }
        return false;

    }

}

结果展示

  • 订单列表
    Pay List

  • 支付详情
    Pay Info

总结

本文只展示了基本的流程,在真正的项目中还要复杂的多。代码已经全部开源到GitHub
线上体验地址 kyle@qq.com/asdfgh http://extended-design-php.kyle.link
GitHub hhttps://github.com/kylesliu/extended-design-php


  Reprint please specify: KYLE LIU PHP简单工厂模式应用

 Previous
Oracle11GR2 RAC DataGuard容灾实施与维护手册 Oracle11GR2 RAC DataGuard容灾实施与维护手册
这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要
2018-10-07
Next 
sql基本练习 sql基本练习
这是你自定义的文章摘要内容,如果这个属性有值,文章卡片摘要就显示这段文字,否则程序会自动截取文章的部分内容作为摘要
2018-10-07
  TOC