【问题标题】:Design Pattern to wrap a series of step包装一系列步骤的设计模式
【发布时间】:2019-05-20 16:37:17
【问题描述】:

我正在提供一项与金融相关的服务,使我们的用户能够在我们的系统中充值余额,然后进行支付。他们将被收取每次付款的费用。 问题是,我需要执行一系列需要在多个地方完成的步骤。

相关组件:

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

业务流程:

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

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

我现在做什么:

  • 创建日记帐分录助手。每个可能的业务流程都包含大量静态功能,涉及在账户之间转移资金。例如在这个问题中,当确认付款时,它把钱从user_deposit 帐户转移到unearned_revenue 帐户,所以user_deposit 将是借方帐户,unearned_revenue 将是新插入日记帐分录中的贷方帐户。这个静态函数中的每一个仅在告诉哪个账户是贷方账户和哪个账户是借方账户方面有所不同。除此之外,此助手还将减少或增加贷记帐户和借记帐户的余额。所以在这个例子中,它将减少user_deposit balance 并增加unearned_revenue balance。与本示例相关的示例函数名称:withdrawPaymentwithdrawTransaction
  • 创建付款助手。不同的支付方式,不同的状态,需要不同的日记账分录助手。所以这个助手中有很多静态函数可以改变付款状态,然后调用相关的日记账助手。与本示例相关的示例函数名称:confirmAndWithdrawCashPayment
  • 在交易上创建一个实例方法,命名为confirmAndwithdraw,它将在付款助手上调用confirmAndWithdrawCashPayment,在日记账助手上调用withdrawTransaction,在日​​记账助手上调用withdrawPayment
  • 每当程序员需要执行此步骤时,他们只需从事务对象中调用confirmAndwithdraw 函数

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

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

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

【问题讨论】:

  • 这个问题不只是太宽泛,它也会主要吸引基于意见的答案(这里是题外话)。
  • 嗨@MagnusEriksson,感谢您的评论。有什么建议可以改善这个问题吗?至少不要太宽泛。
  • 您应该进行大量研究,编写一些代码,如果您在现有代码中遇到某些特定问题,请返回。目前,这个问题在某些论坛上比在 SO 中更适合(这是针对具有具体答案的具体问题)。

标签: php design-patterns


【解决方案1】:

在这种情况下,实例化一个类型需要一定的步骤顺序,我建议您查看构建器模式。通过这种方式,您可以链接所需的步骤并通过存储对象的中间状态随时(延迟)执行它们。完成后,您将调用 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()”的构建实例。 您可以存储中间结果并将其传递并在您喜欢的代码中的任何位置完成它,而不是链接方法调用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    相关资源
    最近更新 更多