Задонатить и смотреть →
Открой безлимитный доступ к 100+ полезных скринкастов и получай скидки на все предстоящие мероприятия

Хранилище состояния и подписка

В прошлом эпизоде мы завершили работу с представлением. А сегодня займёмся усовершенствованной работой с состоянием. Вместо работы с состоянием в виде примитивной структуры мы сделаем полноценный объект-хранилище.

После этого автоматизируем вызов перерендера страницы, реализовав возможность подписывать свои слушатели на событие изменения состояния.

  • 00:01:17 - Создание объекта хранилища
  • 00:03:16 - Изменение состояния в хранилище
  • 00:04:23 - Проблема геттеров и сеттеров
  • 00:09:23 - Метод changeState
  • 00:12:23 - Избавление от геттера через функцию
  • 00:15:37 - Поддержка анонимных функций
  • 00:17:12 - Автоматизация перерендера страницы
  • 00:18:34 - Использование паттерна Наблюдатель
  • 00:19:30 - Реализация подписки на события
  • 00:21:23 - Схема работы приложения
  • 00:23:54 - Что ещё можно улучшить

А в следующем эпизоде активно займёмся доработкой действий.

Скрытый контент (код, слайды, ...) для подписчиков. Открыть →
Дмитрий Елисеев
elisdn.ru
Комментарии (14)
Arunas

Спасибо.

Ответить
Сергей

Вопрос о вредности сеттеров. Если избавиться от сеттеров, то как в том же php инициализировать фикстуры в определенном состоянии? Например статус у фикстуры должен быть processing, а сеттер для статусов я убрал. Как при таком подходе инициализировать фикстуру?

Ответить
Дмитрий Елисеев

Инициализировать через вызовы реальных методов, а не через сеттеры.
Как мы делаем свои фикстуры для регистрации.

Ответить
Сергей

Понятно. Просто в качестве бандла для фикстур используется nelmio/alice . Там декларативный стиль объявления фикстур. А статус меняется только через workflow.

Ответить
Дмитрий Елисеев

В этом как раз и неудобство многих таких готовых декларативных решений вроде Alice, админок, API-бандлов и прочего. Что они умеют работать только с примитивными анемичными сущностями через геттеры и сеттеры.

Ответить
Евгений

Кстати хороший вопрос. Я у В.Вернона читал, что конструктор и мутирующие методы могут вызывать доменные события или другие "побочные эффекты" кроме изменения состояния. Однако есть ещё задача просто восстановить состояние из БД или создать фикстуру. В принципе может быть гидрация через рефлексию. А ещё видел трюк с наследованием сущности для добавления сеттеров полей: при восстановлении используется расширенная версия, а по остальному коду бегает базовая версия без сеттеров.

Ответить
Дмитрий Елисеев

Да, Doctrine и подобные ORM как раз для записи и восстановления из БД используют прямой доступ к приватным полям через рефлексию или bind анонимной функции, не вызывая конструктор. Поэтому там никаких проблем с конструкторами и методами нет.

Ответить
Aёct'ann

Как всегда - высший класс! Спасибо за четкое объяснение без воды.

Ответить
Денис

Спасибо

Ответить
Sergei

Вопрос наверное больше по ООП: в чем преимущество в параметрах методов, таких как calculateTotalPrice(), передавать не сразу весь объект (product например), а только те числовые параметры, которые точно нужны для расчета: product.quantity, product.price И по итогу мы имеем:

calculateTotalPrice(product)

и

calculateTotalPrice(product.quantity, product.price) 

В чем преимущество или недостатки первого и второго? Спсибо

Ответить
Дмитрий Елисеев

1) Если мы пишем тесты, то для второго способа тест будет таким:

assertEqual(75, calculateTotalPrice(3, 25))

А для первого нам нужно будет создать весь объект со всеми даже не нужными нам полями:

product = new Product(1, 'Title')
product.setPrice(25)
product.inStock(3)
assertEqual(75, calculateTotalPrice(product))

2) Первый метод можно использовать только c объектом продукта. А второй метод можем использовать напрямую с числами из БД или кэша.

Ответить
S.Polessky

Значит часть логики Вы предлагаете вынести в некий "экшен" для:

  1. Возможности использования логики повторно.
  2. Лучшей читаемости цепочки действий.
  3. Возможности проводить юнит-тесты.

Но какую часть логики стоит выносить? Оно интуитивно понятно, но хотелось бы определение :)

Ответить
S.Polessky

Насколько понял:

  1. View-часть отвечает за рендер и вызов экшена для вычислений.
  2. Хранилище сохраняет текущее состояние приложения.
  3. Экшены производят вычисления, логическая часть приложения.
Ответить
Дмитрий Елисеев

Верно. В View оставлять только пассивные вычисления и форматирования для отрисовки. А все активные операции, произвдящие изменения, помещать в экшены.

Ответить
Зарегистрируйтесь или войдите чтобы оставить комментарий

Или войти через:

Google
GitHub
Yandex
MailRu