设计模式以包含一系列步骤

时间:2018-12-20 07:04:37

标签: php design-patterns

我正在使用一项与财务相关的服务,该服务使我们的用户能够在他们的系统中充值,然后进行支出。每次付款都会向他们收取费用。 问题是,我需要在多个地方执行一系列步骤。

相关组件:

  • 交易:记录交易信息(金额,收款人账户等)
  • 付款方式:记录付款信息(金额,付款状态)
  • 日记帐分录:记录每次交易和付款的资金流向(对于我们系统中的每笔资金流动,我们都像会计中那样跟踪哪个帐户充当借方帐户,哪个帐户充当贷方帐户)

业务流程流:

  • 假设已经创建了一笔交易和付款,下一步就是确认交易
  • 将交易状态更改为已确认
  • 将付款状态更改为已确认
  • 将新记录插入日记帐分录,并为此流程专门指定借方和贷方帐户
  • 增加或减少贷方帐户的余额

这些步骤系列可能会在几个地方完成,因此我尝试找到一种方法来防止其他试图实现该流程的程序员忘记步骤或做错了。

我现在要做什么:

  • 创建日记条目帮助程序。对于涉及在帐户之间转移资金的每个可能的业务流程,都包含许多静态功能。例如,在这个问题中,当确认付款时,它从user_depositunearned_revenue的帐户中转移了资金,因此user_deposit将成为借方帐户,而unearned_revenue将成为贷方帐户新插入的日记帐分录中的帐户。每个静态函数的区别仅在于,哪个帐户将成为贷方帐户,哪个帐户将成为借方帐户。除此之外,该助手还将减少或增加贷方和借方帐户的余额。因此,在此示例中,它将减少user_deposit余额并增加unearned_revenue余额。与该示例相关的示例函数名称:withdrawPaymentwithdrawTransaction
  • 创建付款助手。不同的付款类型,不同的状态将需要不同的日记帐分录助手。因此,此帮助器中有很多静态功能可以更改付款状态,然后调用相关的日记帐分录帮助器。与该示例有关的示例函数名称:confirmAndWithdrawCashPayment
  • 在交易上创建实例方法,名称类似confirmAndwithdraw,它将在付款帮助程序上调用confirmAndWithdrawCashPayment,在日记账分录帮助程序上调用withdrawTransaction withdrawPayment使用日记帐分录助手。
  • 只要程序员需要执行此步骤,他们就只需从事务对象中调用confirmAndwithdraw函数

这当然可以,但是我也知道这是一个非常糟糕的设计。是否有任何适合这种情况的设计模式建议或解决方案?

主要是,我正在寻找一种包装一系列步骤的方法,以便可以删除那些帮助器类,同时还为其他程序员提供了一种方便的方法来实现此业务流程。

很长的问题很抱歉。如果问题不清楚,请告诉我,以便我提供更多信息。

1 个答案:

答案 0 :(得分:0)

在这种情况下,实例化类型需要一定顺序的步骤,我建议您看一下构建器模式。这样,您可以链接所需的步骤,并通过存储对象的中间状态随时(延迟)执行这些步骤。完成后,您将调用build()来接收初始化的实例。构建器的每个方法都可以返回不同的对象,以便您可以强制客户端仅使用取决于先前调用的操作的方法选择。

可能看起来像这样:

PaymentBuilder paymentBuilder = new PaymentBuilder();
paymentBuilder.OpenTransaction(); 
// PaymentBuilder e.g. has only the OpenTransaction() method which returns a 
// PaymentTransactionOptions instance. This instance contains the 
// state of OpenTransaction() and adds further information by 
// invoking its SetPayment() method. 
paymentBuilder.OpenTransaction(args).SetPaymentMethod(moreArgs); 
// SetPaymentMethod(moreArgs) returns a PaymentJournalOptions instance 
// that contains the prior collected information and a method SetJournalData(). 
paymentBuilder.OpenTransaction(args).SetPaymentMethod(moreArgs).SetJournalData(journalArgs); 

您将像这样继续进行,直到完成交易数据为止。然后,您调用(在最后一个结果对象上)build()以检索可能公开方法'commit()'的构建实例。 无需链接方法调用,您可以存储中间结果并将其传递并在您喜欢的代码中的任何时候完成它。