Skip to content

Feature Clock aware trait

github-actions[bot] edited this page Jul 14, 2026 · 1 revision

🔌 Трейт внедрения — ClockAwareTrait

← Возможности · Главная · Сравнение

Часы в сервисе за три строки: сеттер-инъекция для DI и тестов, фолбэк на глобальный слот, защищённый now() как единая точка чтения времени.

Принцип работы

use CloudCastle\Clock\ClockAwareTrait;

final class InvoiceService
{
    use ClockAwareTrait;

    public function issue(): Invoice
    {
        return new Invoice(issuedAt: $this->now());   // protected now() из трейта
    }
}

Без setClock() сервис читает ClockHolder; с инъекцией — использует переданные часы:

$service = new InvoiceService();
$service->setClock(FrozenClock::from('2026-01-01', 'UTC'));   // тест фиксирует «сегодня»

Методы clock() и now() защищённые и видны наследникам — видимость зафиксирована тестами.

Плюсы

  • Ноль церемоний: не нужен параметр конструктора в каждом сервисе.
  • DI-контейнер с сеттер-инъекцией подключает часы автоматически.

Минусы

  • Скрытая зависимость от ClockHolder при отсутствии инъекции — документируйте это поведение в своих сервисах.

✅ Рекомендуется

  • Сервисы с «текущим временем» в паре мест — там, где отдельный параметр конструктора выглядит перебором.

❌ Антипаттерны

  • Прямые вызовы new DateTimeImmutable() рядом с трейтом — обходят единственную точку времени.

Схема фичи

flowchart LR
    SVC[Сервис + use ClockAwareTrait] -->|"clock()"| Q{внедрены?}
    Q -->|"setClock() вызван"| INJ[Внедрённые часы]
    Q -->|нет| H[ClockHolder::get]
Loading

Жизненный цикл в сервисе

sequenceDiagram
    participant D as DI/Тест
    participant S as Сервис
    participant H as ClockHolder

    alt с инъекцией
        D->>S: setClock(FrozenClock)
        S->>S: now() → замороженный момент
    else без инъекции
        S->>H: get()
        H-->>S: системные часы
    end
Loading

Сравнение с аналогами

Возможность Clock symfony/clock lcobucci/clock beste/clock nesbot/carbon ergebnis/clock 🏆 Победитель
Трейт clock-aware Clock + symfony/clock
Фолбэк на глобальный слот Clock + symfony/clock
Защищённый шорткат now() Clock + symfony/clock

Clone this wiki locally