PHP设计模式建议 - 许多依赖于前面步骤结果的依赖步骤

时间:2013-07-18 09:47:25

标签: php oop design-patterns

简短版本:

如何收集分散在多个对象上的复杂操作的结果?

长版:

我正在开发一个数据交换系统,将客户订单从一个系统推送到另一个系统。这将通过API完成,遗憾的是,在订单成功转移之前,需要按顺序成功完成12个单独的步骤。

虽然每个步骤都可以(并且已经)分解为单独的代码单元,但每个步骤都要按顺序完成,而某些步骤则取决于前面步骤的结果。

是否有适合此特定问题的合适设计图案或图案组合?如果每个步骤都依赖于前一步骤,那么最好的方法是让它了解前面的步骤结果。

我正在考虑使用复合/宏命令设计,或者将OrderPush过程建模为有限状态机,尽管我希望保持它更简单。

这是一个关于系统设计的问题,所以没有必要详细说明API是什么或它是如何工作的,我只期望指向正确的方向。

该过程是从本地系统读取相关数据并通过XMLRPC推送到远程系统。

步骤如下:

  • 创建客户
  • 创建订单(标题记录)
  • 创建订单行
  • 确认订单(这会创建发票)
  • 查找发票
  • 确认发票
  • 创建付款
  • 查找日记帐项目(日记帐项目与发票相关,以便付款行可以与发票绑定)
  • 创建付款行
  • 确认付款

每个步骤都是单个XMLRPC调用,该调用将成功或失败。这就是它的关键。如果未能创建客户,则其他步骤都不起作用。同样,如果订单无法创建,那么其他步骤将失败或无法连接在一起(即如果任何前一步骤失败,我显然应该停止执行。)

所以有人有任何提示吗?

3 个答案:

答案 0 :(得分:1)

对于任何有兴趣的人,我最终偶然发现了一个符合我需求的设计模式。

我的问题可以归结为简单:

如何收集分散在多个对象上的复杂操作的结果?

(我现在已经编辑了这个问题)

答案是收集参数设计模式。 http://sourcemaking.com/implementation-patterns/collecting-parameter

PHP世界中没有太多的例子,尽管它不是一个非常复杂的概念。常识,但我猜这就是所有的设计模式。

我解决它的方法是使用命令模式实现每个单独的操作,命令模式抽象单个操作,以便我可以使用公共接口(即“process()”或“run()”方法)调用它。

鉴于我现在有12个操作可以使用他们自己的process()方法调用,我按顺序触发它们并传入一个通用对象(为清晰起见称为CollectingParameter),其作用只是记录每个操作的结果(因此每个process()方法都必须返回CollectingParameter对象)。 CollectingParameter对象将被传递到下一个操作,然后该操作将可以访问先前操作所需的所有结果。

$operationList = array(new CreateCustomer, new CreateOrder, new CreateOrderLines ... etc)
$collectingParameter = new CollectingParameter;
foreach($operationList as $operation) {
    $collectingParameter = $operation->process($collectingParameter);
}

在各种流程方法中记录和处理错误,这使得process()方法可以自由返回CollectingParameter对象而不是操作结果。

答案 1 :(得分:1)

你真正描述的是一种完成某项工作的算法。 如果这些步骤的顺序非常重要,但有时实现可能会有所不同,那么可能会变为Template method,其中步骤是静态的(即顺序必须相同),但实现可能会有所不同。

您应该查看Command PatternComposite以组成一系列离散步骤,这些步骤可以作为一个例如一个执行。处理()。您还可以查看撤消命令,如果它在流程中途失败,那么这些命令在您的情况下可能很重要。

答案 2 :(得分:0)

如何执行此操作取决于您是否需要在失败点停留,或者如果任何部件失败,您是否希望取消整个批次。

对于前者,它很简单 - 只需在每个步骤进行测试,如果有任何失败,则生成错误报告。

后者有点困难,将取决于您使用的数据库。对于INNODB模式下的Mysql,您可以使用事务,在开始一系列事务之前关闭auto_commit,如果成功则在最后提交,否则回滚事务。

如果您提供有关您希望使用的数据库和访问权限的更多信息,您可能会获得更多帮助。我使用mysqli和mysql作为我的代码,并在创建分布在多个数据库表中的信息的用户时发现它很方便。