@GC8

Как правильно реализовать сервис изменения баланса пользователю вместе с транзакциями?

Есть типы Транзакций: "Пополнение", "Перевод"
Я создал следующие классы с методами для работы с сущностями
class TransactionService {
...
createTransfer(args) {}
createIncrease(args) {}
}

class BalanceService {
   increase(args) {}
   decrease(args) {}
}


В общем писал код следуюшим образом
// Начисляем юзеру на баланс
await BalanceService.increase(args);
// Создаем транзакцию на пополнение
await Transaction.createIncrease(args);


Ну вроде логично все. И тут в задаче появлись новые валюты и типы транзакций и я подумал - "А мое решение вообще адекватное?".

Сейчас чтобы каждый раз например не писать проверку на валюту в разных файлах и вызывать соответствующий метод типа
currencyId === 1 ? BalanceService.increaseRUB(args) : BalanceService.increaseUSD(args);

Я подумал, а что если уже в самом методе транзакций вызывать методы взаимодействия с балансом.
class TransactionService {
  async createIncrease(args) {
      ...
      // тут проверка валюты и начисление баланса
      ... 
  }
}

Как вы считаете норм идея или можно еще как то по другому реализовать?
  • Вопрос задан
  • 109 просмотров
Пригласить эксперта
Ответы на вопрос 1
@Quty
Почему начисление на баланс предшествует созданию транзакции? Что если при создании транзакции возникнет ошибка? Получается, баланс поменяется, а транзакции не будет. Если же на ошибку создания транзакции вызывать списание с баланса, то есть вероятность, что ошибка возникнет при списании.

На мой взгляд баланс должен формироваться из транзакций. Из них всегда можно "построить" текущее состояние баланса пользователя, что-то вроде Event Source.

По поводу валюты. Почему бы её просто не прокидывать в метод создания транзакции? Если на один счёт могут быть транзакции в разных валютах, то можно просто при расчёте баланса брать валюту из транзакции и умножать на курс этой валюты на момент создания транзакции.

Само собой для каждого запроса баланса пользователя не нужно пересчитывать его с "самого начала". Можно кэшировать состояние баланса (создавать snapshot'ы) и при перерасчёте отталкиваться от него.

Если ближе к сути вопроса, то как вариант можно ввести класс для хранения суммы и валюты, прокидывать во всюду его экземпляры вместо простых чисел (сумм). Этот класс (предположим, Money) нужен только для хранения валюты и суммы. А при изменении состояния баланса получать валюту счёта к которому относится транзакция и с помощью какого-нибудь CurrencyService переводить сумму в валюту счёта, после чего изменять остаток счёта.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы