Видео: Scaling Elm Apps by Richard Feldman // Elm Europe 2017
[2:07] Постановка проблемы:
- код сложно найти;
- удержать в голове;
- дублирование;
Код сложно найти
[4:09] Разбивая большое view на дополнительные функции, мы не уменьшили количество строк кода, а наоборот увеличили. Что ж, это не проблема!
Посмотреть как Ричард организовывает структуру проекта и называет переменные можно в его elm-spa-example.
[6:07] Закрыли первую проблему «сложно найти код» -> «организуйте его»: функции-хелперы и организация файловой структуры.
Код приложения сложно удержать в голове
План решения: работаем поэтапно над каждой составляющей.
- view слишком большое — как разбить на части?
- update слишком большой — как разбить на части?
- model слишком большая — как разбить на части?
«Сужаем типы» (Narrowing types)
Для update, руководствуемся той же техникой, и посылаем/получаем необходимый минимум.
[13:23] Разбираем пример: какой профит принесло нам «сужение» в поиске бага в апдейт функции.
[15:05] Разбираемся как сузить Msg.
Вынесли отдельный тип сообщений FeedMsg. И подправили input, чтобы он возвращал Html Msg
, иначе без << будет возвращаться Html FeedMsg
[17:40] начинаем разбираться с проблемой большой модели
Как нам разделить такую модель?
Первая мысль — nested records. Минусы: нужно будет писать больше кода, нужно будет обновлять вложенное поле в update функции. Поэтому, Ричард в этом случае рекомендует взять extensible records.
В видео дается отсылка к материалу Tessa Kelly — Data Structures.
Extensible records подходит для защиты аргументов, а не для моделирования модели данных (Evan Czaplicki)
Дублирование кода
[29:49] начало обсуждения проблемы
Решение — хэлпер функции.
[34:51] как использовать часть интерфейса, без дублирования кода.
- создаем компоненты (сказать точнее — функции), которые используют минимально возможное API (то есть, какие аргументы принимает, какие обработчики имеет и тд)
Отсылка к примеру «более крупного API» — elm-sortable-table (deprecated, подробнее в README проекта)
[39:01] Пример переиспользования формы регистрации
Решение: используем свой msg и свой update, по сути — выделяем форму в отдельный модуль. Для использования в Main модуле, воспользуемся Html.map и Cmd.map
[43:06] Добавляем новую фичу в форму
Не забываем, что update — это функция. Можно вернуть все что угодно:
Каждый раз, когда мы хотим создать что-то «reusable» (для переиспользования), стоит подумать — какое API у нас будет? API должно:
- быть минимально необходимым
- использовать narrow types (узкие типы)
[47:42] Начинаем обсуждать масштабирование с переиспользованием (Scaling with reuse)
Ричард рассказывает про парадигмы. ООП или функциональное программирование. Приводит примеры. Подводит к примеру про несколько открытых дропдаунов на странице. Бизнес требование — должен быть открыт только один. Какое api выберем? Как организуем модель данных? В итоге, в модели вместо статуса открыто/закрыто, хранится dropdownOpen: Maybe DropdownId
. При таком раскладе, мы никак не можем открыть более 1 дропдауна в один момент.
Попутно с дропдаунами обсуждается кейс, когда 2 таба «активны». Хотя такого быть не может.
Можно сказать, с [51:37] Ричард пытается сломать стереотипное ООП-мышление, показывает примеры и подсказывает как это помогло ему.