Самоучитель: PHP 8.5: инженерный практикум
Глава 13 из 22IV. Объектный дизайн105 минут

Глава 13. Value objects, readonly и конечные состояния

Объект полезен, когда делает недопустимое состояние трудным для создания; оболочка с геттерами без правила только увеличивает число файлов.

После главы вы сможете
  • выделить value object
  • применить readonly осознанно
  • смоделировать состояние через enum

Объект отвечает за инвариант

Duration принимает секунды и не позволяет отрицательное значение. ExerciseName гарантирует допустимую длину нормализованного текста. После создания остальной код больше не повторяет одни и те же проверки в контроллере, сервисе и repository.

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

Переход от сырого ввода

Создание предметного значенияКонструктор не получает superglobal и не формирует пользовательское сообщение об ошибке формы.Raw stringboundaryParseformatValidateinvariantValue objectvalidUse casetrusted
Конструктор не получает superglobal и не формирует пользовательское сообщение об ошибке формы.

Readonly — обещание ссылки

readonly-свойство нельзя переназначить после инициализации, но объект, на который оно ссылается, способен иметь собственное изменяемое состояние. Иммутабельность всей модели достигается дизайном, а не одним ключевым словом.

Для обновления immutable-значения создаётся новый экземпляр. PHP 8.5 добавляет clone with, упрощая wither-паттерн для readonly-классов. Фрагмент остаётся необязательным, если проект поддерживает PHP 8.4.

Clone with в PHP 8.5

<?php

readonly class SetTarget
{
    public function __construct(
        public int $repetitions,
        public int $weightGrams,
    ) {}

    public function withWeight(int $grams): self
    {
        return clone($this, ['weightGrams' => $grams]);
    }
}

Enum моделирует закрытый набор

Статус Draft, Published и Archived лучше строк с опечатками и неизвестными значениями. Методы enum могут описывать допустимые переходы, но не должны превращать тип в сервис, который сам пишет в базу или читает текущего пользователя.

Миграция enum требует совместимости между кодом и хранилищем. Сначала база принимает новое значение, затем публикуется код, и только после завершения перехода удаляется старое. Закрытый набор в PHP не отменяет ограничение в базе.

Лабораторная работа

Создайте Duration, Weight и WorkoutStatus. Запретите отрицательные значения, опишите допустимые переходы статуса и покажите обновление immutable-цели без изменения исходного объекта.

Локальный прогресс

Закрепите материал

Отметка, заметка, чек-лист и ответы остаются в localStorage этого браузера и не отправляются в аналитику.

Перелинковка со справочником

Проверка актуальности

  • php.nethttps://www.php.net/releases/8.5/en.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.
  • php.nethttps://www.php.net/manual/en/migration85.phpПервичный источник для актуализации фактов. Адрес приведён как текст и не является активной ссылкой.

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

Данные этого сервиса

Настройки cookie и локальных данных

Аналитика

Текущий статус: не выбран. До согласия обе аналитические системы не загружаются.

Локальные данные

Удаление затрагивает только ключи PHP-сервиса в этом браузере и требует подтверждения.

Политики

Политика конфиденциальности · Политика использования файлов cookie