最近、私はTDDをいじくり回し、SOLIDの原則に基づいてコーディングしています。次のようなシナリオがあります。
- 1つは持つことができます
IRecurringProfile
、それは間隔で、例えば毎月のベースで一連の支払いを実行します - 支払いが完了しようとして失敗すると、に
IRecurringProfileTransaction
リンクされたaが作成されIRecurringProfilePayment
、支払いが完了しなかったことを示します。 - 支払いの失敗数が増加します。
- 支払いを再試行し、別の失敗通知を送信する日時(支払いが失敗した場合)も更新されます。
- 支払いの失敗数が最大しきい値に達すると(たとえば、3回失敗した場合)、
IRecurringProfile
は一時停止されます。 - また、失敗するたびに、支払いが完了しなかったことをクライアントに通知する通知が送信され、再試行されます。
以下は私が作成したサンプルコードです。これは主に、定期的なプロファイル支払いを失敗としてマークするタスクを扱います。私は、コンストラクターの注入だけでなく、SOLIDの原則にも従おうとしました。これがこれらの原則またはプログラミングのベストプラクティスのいずれかに違反しているかどうかを知り、コードを改善できるようにあらゆる形式の精査の対象にします。このコードでは、ORMとしてNHibernateも使用しています。
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;
}
}
}
-
ちなみに、この質問は、同様のトピックに関する私の最新の投稿を補足するものです。