Skip to content

Architecture

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

Архитектура

Пространство имён

Пакет использует PSR-4 namespace CloudCastle\Clock\ (каталог src/) с подслоями:

  • CloudCastle\Clock\Contract\ — интерфейсы (публичные контракты);
  • CloudCastle\Clock\Exception\ — исключения пакета;
  • CloudCastle\Clock\… — реализация.

Архитектурные границы между слоями проверяются Deptrac: Core зависит от Contract/Exception/External, Contract не зависит от Core.

Тесты

CloudCastle\Clock\Tests\ (каталог tests/) разделён на наборы: Unit, Integration, Security, Load, Performance.

Принципы

  • Строгая типизация, declare(strict_types=1) в каждом файле.
  • Минимум runtime-зависимостей.
  • Публичный API документирован PHPDoc.

Схема контрактов и реализаций

classDiagram
    class PsrClockInterface {
        <<interface>> Psr\Clock
        +now() DateTimeImmutable
    }
    class ClockInterface {
        <<interface>>
        +timestamp() int
        +microtime() float
        +timezone() DateTimeZone
        +withTimezone(tz) static
    }
    class SleepableClockInterface {
        <<interface>>
        +sleep(seconds) void
        +sleepUntil(moment) void
    }
    class AdjustableClockInterface {
        <<interface>>
        +setTo(moment) void
        +modify(modifier) void
        +advance(duration) void
        +rewind(duration) void
    }

    PsrClockInterface <|-- ClockInterface
    ClockInterface <|-- SleepableClockInterface
    ClockInterface <|-- AdjustableClockInterface

    ClockInterface <|.. SystemClock
    SleepableClockInterface <|.. SystemClock
    AdjustableClockInterface <|.. FrozenClock
    AdjustableClockInterface <|.. MockClock
    SleepableClockInterface <|.. MockClock
    ClockInterface <|.. MonotonicClock
    ClockInterface <|.. CallbackClock
    ClockInterface <|.. OffsetClock
    ClockInterface <|.. ScaledClock
    ClockInterface <|.. TruncatingClock

    OffsetClock o-- ClockInterface : декорирует
    ScaledClock o-- ClockInterface : декорирует
    TruncatingClock o-- ClockInterface : декорирует
Loading

Поток времени: прод и тест

flowchart LR
    subgraph Прод
        A[Сервис] -->|"clock()"| T[ClockAwareTrait]
        T -->|инъекции нет| H[ClockHolder]
        H -->|дефолт| S[SystemClock]
        S -->|"now()"| OS[(Системное время)]
    end

    subgraph Тест
        A2[Тот же сервис] -->|"setClock()"| M[MockClock]
        M -->|"sleep(3600) — мгновенно"| V[(Виртуальное время)]
    end
Loading

Как декораторы сохраняют связь с источником

withTimezone() у декораторов не копирует внутренние часы, а создаёт новый декоратор над теми же часами: сдвиги управляемого источника видны всем декораторам поверх него.

flowchart TD
    MC[MockClock 10:00] --> SC["ScaledClock ×60"]
    SC -->|withTimezone Moscow| SC2["ScaledClock ×60 (Moscow)"]
    MC -.->|"advance(1s) виден обоим"| SC
    MC -.-> SC2
Loading

Clone this wiki locally