Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як моделювати гроші, періоди часу й статуси в домені, щоб уникнути помилок?

Гроші, час і статуси - три типи даних, які найчастіше моделюють «примітивами» (float, string, int) і які дають найбільше помилок.

Гроші:

  • не float: 0.1 + 0.2 ≠ 0.3. Сума в мінімальних одиницях (копійках) цілим числом або decimal у базі;
  • валюта завжди поруч з сумою: 100 - це гривні чи долари? Додавання сум у різних валютах має бути помилкою, а не мовчазним результатом;
  • об'єкт-значення Money (власний чи бібліотека moneyphp/money, brick/money) збирає правила в одному місці: додавання, порівняння, округлення, розподіл без втрат (100 грн на 3 частини - 33,34 + 33,33 + 33,33, а не три по 33,33 з загубленою копійкою).

Час:

  • мить у часі - CarbonImmutable в UTC; у місцевий час перетворювати лише для показу;
  • дата без часу (день народження, дата події) - окремий тип, а не DateTime з опівнічним часом, який зміщується в іншому поясі;
  • період - об'єкт DateRange з початком і кінцем і методами contains(), overlaps() замість пари змінних і перевірок, розкиданих по коду;
  • незмінні дати (CarbonImmutable, Date::use(CarbonImmutable::class)) - щоб $start->addDay() не змінював оригінал непомітно;
  • «зараз» як залежність: код, що порівнює з поточним часом, легше тестувати, якщо час можна підмінити (Carbon::setTestNow, $this->travelTo()).

Статуси:

  • енум замість рядків і чисел: OrderStatus::Paid замість 'paid' чи 3;
  • дозволені переходи - у моделі чи енумі (canTransitionTo()), а не в if по всьому коду;
  • без суперечливих прапорців: is_paid, is_shipped, is_cancelled дозволяють неможливі комбінації - один статус робить їх невиразними.

У Laravel все це підтримується з коробки: касти енумів ('status' => OrderStatus::class), власні касти для Money, immutable_datetime.

Загальна ідея - «примітивна одержимість» (primitive obsession) як запах коду: якщо значення має правила (формат, діапазон, операції), воно заслуговує на власний тип.

Докладніше в документації: Martin Fowler: Money

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання