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


PHP Design Pattern Advice - many dependant steps that rely on results from previous steps

短版本:

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

长版本:

我正在开发一个数据交换系统,将客户订单从一个系统推送到另一个系统。这将通过API完成,不幸的是,这需要按顺序成功完成12个单独的步骤,然后才能报告订单成功转移。

尽管每个步骤都可以(并且已经)分解为单独的代码单元,但每个步骤都必须按顺序完成,有些步骤取决于之前步骤的结果。

是否有适合这个特定问题的设计模式或模式组合?如果每一步都依赖于前一步,那么让它知道前一步结果的最佳方法是什么。

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

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

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

步骤是:

  • 创建客户
  • 创建订单(表头记录)
  • 创建订单行
  • 确认订单(这将创建发票)
  • 查找发票
  • 确认发票
  • 创建付款
  • 查找日记账项目(日记账项目与发票相关,以便付款行可以绑定到发票)
  • 创建付款行
  • 确认付款

每个步骤都是一个XMLRPC调用,它要么成功,要么失败。这就是问题的关键。如果客户创建失败,那么其他步骤都不会奏效。类似地,如果订单未能创建,那么其他步骤将失败或无法结合在一起(即,如果之前的任何步骤失败,我显然应该停止执行)。

有人有什么建议吗?

对于任何感兴趣的人来说,我终于偶然发现了一种适合我需求的设计模式。

我的问题可以简化为:

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

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

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

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

我解决这个问题的方法是使用命令模式实现每个单独的操作,命令模式抽象了一个操作,这样我就可以使用一个公共接口(即"process()"或"run()"方法)调用它。

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

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

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

您真正描述的是一种完成任务的算法。如果这些步骤的顺序非常重要,但有时实现可能会有所不同,那么这可能会成为一种模板方法,其中步骤是静态的(即顺序必须相同),但实现可能会不同。

您应该查看命令模式和Composite来组成一个离散步骤树,这些步骤可以作为一个整体执行,例如process()。您还可以查看undo命令,如果它在流程的中途失败,这在您的情况下可能很重要。

如何做到这一点取决于您是否需要在故障点停止,或者如果任何部分出现故障,您是否希望取消整个批次。

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

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

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