timehunter/delivery-order-test

dev-master 2019-03-15 00:25 UTC

This package is auto-updated.

Last update: 2024-09-15 12:40:36 UTC


README

Coverage Status Build StyleCI

2019年3月15日更新

我刚刚快速添加了一种新的替代方法,即在 DeliveryOrderModule/Strategy 文件夹下使用策略模式。策略模式适用于需要完全解耦并分布到任何地方的类。

注意:我还没有为策略模式添加测试。说实话,我仍然更喜欢模板方法,将所有重复代码放入父类中,这样所有子类都可以共享这些代码。而且,需求明确指出每个配送订单都有自己的工作流程,这是在父类(AbstractDeliveryOrderProcessor)中定义步骤的完美用例。

(策略模式只是一个附加的展示,它没有测试等...)

描述

该解决方案是在 Laravel 框架上编写的。

安装

  1. 这是一个 Laravel composer 包,您首先需要安装 Laravel。
  2. 通过 Composer
$ composer require timehunter/delivery-order-test

问题分析

可用于此问题的潜在设计模式:工厂模式、模板方法和策略模式

可以将问题归纳为以下要点

  1. 如何根据动态输入值创建不同的对象?例如,“enterpriseDelivery”返回 EnterpriseDelivery 对象
  • 使用工厂模式封装创建对象的逻辑。
  1. 不同的对象应包含自己的工作流程和依赖服务。
  • 使用策略模式(接口)或模板方法(继承)
  1. 领域驱动设计
  • 基本思路是将系统构建为模块化,每个模块都有自己的服务。如果有任何公共接口,则可以在不同模块之间共享。
  • 从提到的问题中,我发现有三个模块可以找到:配送订单模块、第三方模块和营销模块

我的解决方案

假设

  1. 营销服务和第三方 API 服务已经过全面测试。

设计

  1. 我使用基于继承的模板方法设计模式。它允许我通过在子类中扩展这些部分来修改算法的部分。
  2. 我还使用工厂模式来确定需要返回哪种类型的配送订单对象。

注意

  1. 如问题所述,企业配送订单需要先与第三方 API 进行验证,如果验证失败,则不再继续执行逻辑。在这种情况下,我定义了在抽象类中的步骤,例如先验证,然后执行逻辑。
....
    public function process()
    {
        if ($this->validate()) {
            $this->before();
            $this->handle();
            $this->after();

            return true;
        } else {
            return false;
        }
    }
....

handle 函数是一个抽象函数,它将在所有子类中实现。使用此函数来定义其自己的工作流程。

使用

 $json = "[{},{},{}...{}]"; // the given sample json data
 $service = new DeliveryOrderService($json);
 $objects = $service->processJson() // this return a list of different delivery order objects
 
 

测试

  1. 使用 PHPUnit
  2. 对接口进行模拟以进行测试
  3. 传递不同的 JSON 进行测试,以检查服务是否返回正确的配送类型
  4. 使用 travis-ci 进行 CI/CD:https://coveralls.io/github/RyanDaDeng/delivery-order-test?branch=master

改进与关联

  1. 该包不使用 Laravel 功能,例如服务容器、门面。可以通过创建服务提供程序来注册其依赖项。
  2. API 服务和营销服务可以是单例。
  3. 如果出现新的配送订单类型,我们只需要创建一个新的子类,该子类扩展了抽象基类,而不需要修改源代码(开放扩展)。
  4. 如果接口和设计最终确定,可以使用策略模式代替继承。
  5. 可以在抽象类上实现异常处理程序。