timehunter / delivery-order-test
:描述
dev-master
2019-03-15 00:25 UTC
Requires
Requires (Dev)
- mockery/mockery: ^1.1
- orchestra/testbench: ~3.0
- php-coveralls/php-coveralls: ^2.1
- phpunit/phpunit: ~7.0
- sempro/phpunit-pretty-print: ^1.0
This package is auto-updated.
Last update: 2024-09-15 12:40:36 UTC
README
2019年3月15日更新
我刚刚快速添加了一种新的替代方法,即在 DeliveryOrderModule/Strategy 文件夹下使用策略模式。策略模式适用于需要完全解耦并分布到任何地方的类。
注意:我还没有为策略模式添加测试。说实话,我仍然更喜欢模板方法,将所有重复代码放入父类中,这样所有子类都可以共享这些代码。而且,需求明确指出每个配送订单都有自己的工作流程,这是在父类(AbstractDeliveryOrderProcessor)中定义步骤的完美用例。
(策略模式只是一个附加的展示,它没有测试等...)
描述
该解决方案是在 Laravel 框架上编写的。
安装
- 这是一个 Laravel composer 包,您首先需要安装 Laravel。
- 通过 Composer
$ composer require timehunter/delivery-order-test
问题分析
可用于此问题的潜在设计模式:工厂模式、模板方法和策略模式
可以将问题归纳为以下要点
- 如何根据动态输入值创建不同的对象?例如,“enterpriseDelivery”返回 EnterpriseDelivery 对象
- 使用工厂模式封装创建对象的逻辑。
- 不同的对象应包含自己的工作流程和依赖服务。
- 使用策略模式(接口)或模板方法(继承)
- 领域驱动设计
- 基本思路是将系统构建为模块化,每个模块都有自己的服务。如果有任何公共接口,则可以在不同模块之间共享。
- 从提到的问题中,我发现有三个模块可以找到:配送订单模块、第三方模块和营销模块
我的解决方案
假设
- 营销服务和第三方 API 服务已经过全面测试。
设计
- 我使用基于继承的模板方法设计模式。它允许我通过在子类中扩展这些部分来修改算法的部分。
- 我还使用工厂模式来确定需要返回哪种类型的配送订单对象。
注意
- 如问题所述,企业配送订单需要先与第三方 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
测试
- 使用 PHPUnit
- 对接口进行模拟以进行测试
- 传递不同的 JSON 进行测试,以检查服务是否返回正确的配送类型
- 使用 travis-ci 进行 CI/CD:https://coveralls.io/github/RyanDaDeng/delivery-order-test?branch=master
改进与关联
- 该包不使用 Laravel 功能,例如服务容器、门面。可以通过创建服务提供程序来注册其依赖项。
- API 服务和营销服务可以是单例。
- 如果出现新的配送订单类型,我们只需要创建一个新的子类,该子类扩展了抽象基类,而不需要修改源代码(开放扩展)。
- 如果接口和设计最终确定,可以使用策略模式代替继承。
- 可以在抽象类上实现异常处理程序。