On service logic processing module using a modular approach mode

Because the process of reading yii2 source, not understanding its design patterns (cause it more difficult to read), a design pattern which describes in which used: Method mode module.

Method mode module concept:

    The algorithm defines a skeleton of the operation, some steps to subclasses delay. Template Method lets subclasses may not change the structure of an algorithm to redefine certain steps of the algorithm (reference: novice Tutorial ). Design of a service processing logic in the learning process.

Directory Structure:

/index.php demo file

/autoload.php class load file

abstract service logic processing class /sour/AbstractService.php

/sour/ServiceGo.php specific business logic implementation class

 

index.php

<?php
namespace design;

use \design\sour\ServiceGoShop;

require 'autoload.php';
spl_autoload_register('auto_loader');

/**
 * 利用模块方法模式,实现一个业务逻辑模块的格式化
 */
$action = new ServiceGo();  //创建一个Go业务服务
//去旅行
$result = $action->run('travel', [
    'where' => '蓝天之上',
    'money' => 100
]);
echo json_encode($result, JSON_UNESCAPED_UNICODE).'<br>';
//去购物
$result = $action->run('goShop', [
    'money' => 100
]);
echo json_encode($result, JSON_UNESCAPED_UNICODE).'<br>';

autoload.php

<?php

defined('PATH') or define('PATH', __DIR__);

function auto_loader($class)
{
    $path = str_replace(
        '\\',
        DIRECTORY_SEPARATOR,
        substr($class, strpos($class, '\\', 1)+1)
    );
    if(file_exists(PATH.DIRECTORY_SEPARATOR.$path.'.php')) {
        require PATH.DIRECTORY_SEPARATOR.$path.'.php';
    } else {
        throw new Exception(sprintf('not found `%s`', $class));
    }
    return class_exists($class);
}

/sour/AbstractService.php

<?php
namespace design\sour;


use \Exception;

define('RESULT_CODE', 0);
define('RESULT_MSG', 'success');
define('RESULT_DATA', []);
define('PARAMS', []);

abstract class AbstractService
{

    protected $code = RESULT_CODE;

    protected $msg = RESULT_MSG;

    protected $data = RESULT_DATA;

    public $params = [];

    public abstract function process($method);

    public abstract function getPrefix();

    /**
     * 通过__get方法, 获取具体的服务动作需要的参数
     * @param $name
     * @return mixed
     */
    public function __get($name)
    {
        if(isset($this->params[$name])) {
            return $this->params[$name];
        } else {
            throw new Exception('not found parameter `%s`', $name);
        }
    }

    /**
     * 通过__set方法缓存具体的服务动作访问到的参数
     * @param $name
     * @param $value
     */
    public function __set($name, $value)
    {
        $this->params[$name] = $value;
    }

    /**
     * 业务开始之前的业务属性初始化
     */
    private function init()
    {
        $this->params = PARAMS;
        $this->code = RESULT_CODE;
        $this->msg = RESULT_MSG;
        $this->data = RESULT_DATA;
    }

    /**
     * 初始化方法传参
     * @param $args
     */
    private function initParams($args)
    {
        foreach ($args as $name => $value) {
            $this->{$name} = $value;
        }
    }

    /**
     * 统一业务返回参数
     * @return array
     */
    private function ret()
    {
        return [
            'code' => $this->code,
            'msg' => $this->msg,
            'data' => $this->data
        ];
    }

    /**
     * 业务逻辑入口,
     * @param $method 所调用的业务类方法
     * @param $args   业务类所用传参
     * @return array
     */
    public function run($method, $args)
    {
        $this->init();
        $this->initParams($args);
        $this->process($method);
        return $this->ret();
    }

    /**
     * 格式化方法名称
     * @param $method
     * @return string
     */
    public function normalizeMethod($method)
    {
        return $this->getPrefix().ucwords($method);
    }

}

/sour/ServiceGo.php

<?php

namespace design\sour;

use \Exception;

class ServiceGo extends AbstractService
{

    /**
     * 具体的业务代码(去旅行)
     */
    public function goTravel()
    {
        do {
            if(bccomp($this->money, '0', 2) <= 0) {
                $this->code = 10001;
                $this->msg = '没有钱';
                break;
            }
            if(!$this->where) {
                $this->code = 10002;
                $this->msg = '不知道去哪儿';
                break;
            }
            $this->data = [
                'where' => $this->where,
                'money' => $this->money
            ];
        } while(false);
    }

    /**
     * 具体的业务代码(购物)
     */
    public function goGoShop()
    {
        do {
            if(bccomp($this->money, '0', 2) <= 0) {
                $this->code = 10001;
                $this->msg = '没有钱';
                break;
            }
            $this->data = [
                'buy' => [
                    'vegetables' => [
                        '胡罗卜',
                        '白菜'
                    ],
                    'fruit' => [
                        '葡萄',
                        '香蕉',
                        '哈密瓜'
                    ]
                ]
            ];
        } while(false);
    }

    /**
     * 返回方法的前缀
     * @return string
     */
    public function getPrefix()
    {
        return 'go';
    }

    /**
     * 服务类过程处理
     * @param $method
     * @throws Exception
     */
    public function process($method)
    {
        $normalizeMethod = $this->normalizeMethod($method);
        if(!method_exists($this, $normalizeMethod)) {
            throw new Exception(sprintf('class `%s` not found method `%s`', get_class($this), $method));
        }
        $this->{$normalizeMethod}();
    }

}

 

 Oh ~

Published 31 original articles · won praise 3 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_36557960/article/details/99240183