Дизайн шаблона, чтобы обернуть серию шагов - PullRequest
0 голосов
/ 20 декабря 2018

У меня есть служба, связанная с финансами, которая позволяет нашим пользователям пополнять баланс в нашей системе, а затем выплачивать деньги.Они будут платить за каждую выплату.Проблема в том, что мне нужно выполнить ряд шагов, которые необходимо выполнить в нескольких местах.

Связанный компонент:

  • Транзакция: запись информации о транзакции(сумма, счет получателя и т. д.)
  • Платеж: запись информации об оплате (сумма, статус платежа)
  • Записи в журнале: запись движения денег для каждой транзакции и платежа (для каждого движенияденег в нашей системе мы отслеживаем, какой счет действует как дебетовый, а какой - как кредитный, как в бухгалтерии)

Поток бизнес-процесса:

  • Предположим, что транзакция и платеж уже созданы, следующим шагом является подтверждение транзакции
  • Изменить статус транзакции на подтвержденный
  • Изменить статус платежа на подтвержденный
  • Вставить новую запись в записи журнала, с дебетовым и кредитным счетом, указанным специально для этого процесса
  • Увеличение или уменьшение баланса кредитного и дебетового счета

Эта серия шагов может быть выполнена в нескольких местах, поэтому я пытаюсь найти способ, чтобы другие программисты, пытающиеся реализовать этот поток, не могли забыть шаг или сделать его неправильно.

Что я делаю сейчас:

  • Создание помощника по записи в журнале .Состоят из множества статических функций для каждого из возможных бизнес-процессов, которые включают перемещение денег между счетами.Например, в этом вопросе при подтверждении платежа он переместил деньги со счета user_deposit на unearned_revenue, поэтому user_deposit будет дебетовым счетом, а unearned_revenue будет кредитным счетом во вновь добавленной записи журнала.Каждая из этих статических функций отличается только сообщением, какой счет будет кредитным, а какой - дебетовым.Кроме того, этот помощник также уменьшит или увеличит баланс кредитного и дебетового счета.Таким образом, в этом примере он будет уменьшать user_deposit баланс и увеличивать unearned_revenue баланс.Пример имени функции, относящейся к этому примеру: withdrawPayment и withdrawTransaction
  • Создать помощника по оплате .Для разных типов платежей в разных штатах потребуется другой помощник по записи в журнале.Таким образом, в этом помощнике много статических функций, которые изменяют статус платежа, а затем вызывают соответствующий помощник записи журнала.Пример имени функции, относящейся к этому примеру: confirmAndWithdrawCashPayment
  • Создание экземпляра метода для транзакции с именем, подобным confirmAndwithdraw, который будет вызывать confirmAndWithdrawCashPayment для помощника по оплате и withdrawTransaction дляпомощник по записи в журнал, который вызовет withdrawPayment для помощника по записи в журнал.
  • Когда программисту необходимо выполнить этот шаг, он просто вызывает функцию confirmAndwithdraw из объекта транзакции

Это будет работать, конечно, но я также знаю, что это очень плохой дизайн.Любое предложение дизайна шаблона или любое решение, подходящее для этого случая?

В основном я ищу способ обернуть серию шагов, чтобы можно было удалить эти вспомогательные классы, а также предоставить удобный способ для других программистов реализовать этот бизнес-процесс.

Извините за длинный вопрос.Если вопрос не ясен, пожалуйста, скажите мне, чтобы я мог предоставить больше информации.

1 Ответ

0 голосов
/ 21 декабря 2018

В подобных сценариях, где создание экземпляра типа требует определенного порядка шагов, я рекомендую взглянуть на шаблон Builder.Таким образом, вы можете связать необходимые шаги и выполнить их в любое время (отложенное), сохраняя промежуточное состояние объекта.Когда вы закончите, вы вызовете 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 ().Вместо цепочки вызовов метода вы можете сохранить промежуточный результат, передать его и завершить в любой момент в коде, который вам нравится.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...