最近我一直在修补 TDD 和基于 SOLID 原则的编码。我有一个场景如下:
- 一个可以有
IRecurringProfile
,它会按一定时间间隔(例如按月)执行一系列付款 - 当付款尝试通过但失败时,
IRecurringProfileTransaction
会创建一个链接到IRecurringProfilePayment
以显示付款未通过。 - 付款失败计数增加。
- 重试付款并发送另一个失败通知(如果付款失败)的日期/时间也会更新。
- 如果支付的失败计数达到最大阈值(例如 3 次失败尝试),
IRecurringProfile
则暂停。 - 此外,每次失败时,都会发送通知通知客户付款未通过,并将再次重试。
下面是我创建的一些示例代码,主要处理将定期付款资料标记为失败的任务。我尝试遵循 SOLID 原则以及构造函数注入。想知道这是否违反了这些原则或任何编程最佳实践,并对代码进行任何形式的审查,以便对其进行改进。该代码还使用 NHibernate 作为 ORM。
public class RecurringPaymentMarkAsFailure
{
private readonly IPaymentFailedNotificationSender paymentFailedNotificationSender;
private readonly IRecurringProfileFailureNextNotificationDateUpdater failureNotificationDateUpdater;
private readonly IRecurringProfileSuspender recurringProfileSuspender;
public RecurringPaymentMarkAsFailure(IPaymentFailedNotificationSender paymentFailedNotificationSender, IRecurringProfileSuspender recurringProfileSuspender,
IRecurringProfileFailureNextNotificationDateUpdater failureNotificationDateUpdater)
{
this.paymentFailedNotificationSender = paymentFailedNotificationSender;
this.failureNotificationDateUpdater = failureNotificationDateUpdater;
this.recurringProfileSuspender = recurringProfileSuspender;
}
private void checkProfileStatus(IRecurringProfile profile)
{
if (profile.Status != Enums.RecurringProfileStatus.Active)
{
throw new Exceptions.RecurringProfileException("This cannot be called when the profile is not marked as active");
}
}
private void incrementFailureCount(IRecurringProfilePayment payment)
{
payment.FailureCount++;
}
public IRecurringProfileTransaction MarkPaymentAsFailed(IRecurringProfilePayment payment, string failureData)
{
using (var t = BeginTransaction())
{
checkProfileStatus(payment.RecurringProfile);
IRecurringProfileTransaction transaction = payment.Transactions.CreateNewItem();
transaction.OtherData = failureData;
transaction.Status = Enums.RecurringProfileTransactionStatus.Failure;
paymentFailedNotificationSender.CreateAndQueueNotification(transaction);
failureNotificationDateUpdater.UpdateNextFailureNotificationDate(payment);
incrementFailureCount(payment);
if (payment.FailureCount >= payment.RecurringProfile.MaximumFailedAttempts)
{
recurringProfileSuspender.SuspendRecurringProfile(payment.RecurringProfile);
}
transaction.Save();
t.Commit();
return transaction;
}
}
}
--
作为旁注,这个问题补充了我最近关于类似主题的帖子。