Введение
В этом канале хочу описать ряд мыслей, которые сформировались по ходу работы. В основном они про архитектуру front-end приложений.
Также, я работаю сейчас на языке Dart, в проектах использую Flutter. Поэтому часть постов будет более актуальна именно для этого стека. Я постараюсь помечать это тегами.
В основном, я придерживаюсь подхода Clean Architecture. Я буду говорить о бизнес-логике, о бизнес-моделях, провайдерах, сторейджах, презентаторах и представлениях, и как все это реализовать во Flutter-проектах, и почему это все надо реализовывать.
Основные действующие лица:
- Модель — это класс, описывающий единицу данных, с которыми работает приложение: "пользователь", "задача", "проект".
- Логика — это use cases, варианты использования. Это действия, которые пользователь может совершить над данными, чтобы их изменить. Например, "изменить права пользователя".
- Презентатор — платформо независимая штука, которая подготавливает данные к отображению и обрабатывает действия пользователя.
- ВьюМодель, ViewModel — класс, который содержит данные, необходимые для отображения интерфейса пользователя: подготовленные данные моделей, состояния экрана и т.д.
- Представление — реализация интерфейса пользователя, код, написанный на каком-то фреймверке, зависимый от платформы.
- data source — класс, загружающий данные из внешнего источника.
- Фактори — класс, который раздает конкретные реализации интерфейсов. Нужен для установки архитектурных границ.
Не все мысли являются законченными. Часто с опытом я их пересматриваю, ищу лучшие решения.
В этом канале хочу описать ряд мыслей, которые сформировались по ходу работы. В основном они про архитектуру front-end приложений.
Также, я работаю сейчас на языке Dart, в проектах использую Flutter. Поэтому часть постов будет более актуальна именно для этого стека. Я постараюсь помечать это тегами.
В основном, я придерживаюсь подхода Clean Architecture. Я буду говорить о бизнес-логике, о бизнес-моделях, провайдерах, сторейджах, презентаторах и представлениях, и как все это реализовать во Flutter-проектах, и почему это все надо реализовывать.
Основные действующие лица:
- Модель — это класс, описывающий единицу данных, с которыми работает приложение: "пользователь", "задача", "проект".
- Логика — это use cases, варианты использования. Это действия, которые пользователь может совершить над данными, чтобы их изменить. Например, "изменить права пользователя".
- Презентатор — платформо независимая штука, которая подготавливает данные к отображению и обрабатывает действия пользователя.
- ВьюМодель, ViewModel — класс, который содержит данные, необходимые для отображения интерфейса пользователя: подготовленные данные моделей, состояния экрана и т.д.
- Представление — реализация интерфейса пользователя, код, написанный на каком-то фреймверке, зависимый от платформы.
- data source — класс, загружающий данные из внешнего источника.
- Фактори — класс, который раздает конкретные реализации интерфейсов. Нужен для установки архитектурных границ.
Не все мысли являются законченными. Часто с опытом я их пересматриваю, ищу лучшие решения.
Безопасное программирование
Выделю два типа ошибок в коде: ошибки, которые есть прям щас, и ошибки будущие.
Первый тип ошибок устранять в основном просто: запусти код и убедись, что он работает. Можно даже написать тесты для проверки. Или даже сначала написать тесты, а потом код, который их проходит.
Второй тип ошибок сложный для обнаружения и исправления.
Например, в одном месте проекта есть перебор вариантов значения параметра value через множество
В реальности это может выглядеть так, что в каком-то далеком диалоговом окне, на первый взгляд слабо связанным с новыми изменениями кода, не отобразятся дополнительные параметры, или даже будет исключение при попытке его открыть.
Если бы перебор значений происходил не с помощью условий, а с помощью оператора выбора
То есть, если мы пишем код определенным образом, ошибки становятся очевидными и простыми для исправления. Это я и называю безопасным программированием.
Многие архитектурные решения в большой степени существуют и для того, чтобы код был безопасным.
Выделю два типа ошибок в коде: ошибки, которые есть прям щас, и ошибки будущие.
Первый тип ошибок устранять в основном просто: запусти код и убедись, что он работает. Можно даже написать тесты для проверки. Или даже сначала написать тесты, а потом код, который их проходит.
Второй тип ошибок сложный для обнаружения и исправления.
Например, в одном месте проекта есть перебор вариантов значения параметра value через множество
if-else. Когда через месяц в другом месте проекта мы расширим набор возможных значений value, ничто не скажет нам о том, что нужно изменить первое место.В реальности это может выглядеть так, что в каком-то далеком диалоговом окне, на первый взгляд слабо связанным с новыми изменениями кода, не отобразятся дополнительные параметры, или даже будет исключение при попытке его открыть.
Если бы перебор значений происходил не с помощью условий, а с помощью оператора выбора
switch, статический анализатор сразу бы показал необходимые места исправлений.То есть, если мы пишем код определенным образом, ошибки становятся очевидными и простыми для исправления. Это я и называю безопасным программированием.
Многие архитектурные решения в большой степени существуют и для того, чтобы код был безопасным.
Не слушайте модели
Однажды мальчик использовал на проекте мутабельные модели... И у него отвалилась жопа.
Были времена еще первых версий языка Dart и веб-фреймверка Polymer v0.5. И было задание написать программу для редактирования и просмотра всяких дашбордов. Дашборды состояли из виджетов, были группы, было миллион пропертей и внутренний язык программирования.
Когда дело дошло до экрана редактора, нужно было, чтобы изменения параметров виджета мгновененько отображались в центральной части экрана.
Был там такой интерфейс
Сначала было все прекрасно. Немного поработал, чтобы не было бесконечного цикла обновлений между вьшкой панели свойств виджета и компонентом, отображающим его на экране.
Лежу и жмурюсь, все так мгновенно меняется, а мне и делать не сильно чего надо было. Красота!
Но вот Google Chome сказал: "А ну ка все обновили Shadow Dom, а то ваши сайты работать не будут." То есть, надо было перебираться на новые версии своих фреймверков, так как спецификация WebComponents опять изменилась.
Полимер вдруг умер, а пакет observable обновился, потеряв обратную совместимость.
И к черту полимер, есть и другие фреймверки. Но вот только этот
За несколько месяцев аккуратного рефакторинга я так и не смог перенести весь проект на новый фреймверк, осталось несколько очень толстых компонентов. Этот перенос отменили, я нашел всякие хаки и устранил несовместимости с современными браузерами. И по сей день этот монстр так и поддерживается на очень старой базе кода и древних зависимостях.
О чем это я. Никогда, никогда не используйте никакие сторонние библиотеки в слоях бизнес-логики и бизнес-моделей. И никогда не делайте модели прослушиваемыми. Пусть будут иммутабельными.
Однажды мальчик использовал на проекте мутабельные модели... И у него отвалилась жопа.
Были времена еще первых версий языка Dart и веб-фреймверка Polymer v0.5. И было задание написать программу для редактирования и просмотра всяких дашбордов. Дашборды состояли из виджетов, были группы, было миллион пропертей и внутренний язык программирования.
Когда дело дошло до экрана редактора, нужно было, чтобы изменения параметров виджета мгновененько отображались в центральной части экрана.
Был там такой интерфейс
Observable, с помощью которого дарт мог заполнять HTML шаблоны данными. И вот пришла идея все-все данные этого дашборда хранить как observable-классы.Сначала было все прекрасно. Немного поработал, чтобы не было бесконечного цикла обновлений между вьшкой панели свойств виджета и компонентом, отображающим его на экране.
Лежу и жмурюсь, все так мгновенно меняется, а мне и делать не сильно чего надо было. Красота!
Но вот Google Chome сказал: "А ну ка все обновили Shadow Dom, а то ваши сайты работать не будут." То есть, надо было перебираться на новые версии своих фреймверков, так как спецификация WebComponents опять изменилась.
Полимер вдруг умер, а пакет observable обновился, потеряв обратную совместимость.
И к черту полимер, есть и другие фреймверки. Но вот только этот
Observable насколько густо пропитал проект, что наверное, в нем увязло более 80% всех классов.За несколько месяцев аккуратного рефакторинга я так и не смог перенести весь проект на новый фреймверк, осталось несколько очень толстых компонентов. Этот перенос отменили, я нашел всякие хаки и устранил несовместимости с современными браузерами. И по сей день этот монстр так и поддерживается на очень старой базе кода и древних зависимостях.
О чем это я. Никогда, никогда не используйте никакие сторонние библиотеки в слоях бизнес-логики и бизнес-моделей. И никогда не делайте модели прослушиваемыми. Пусть будут иммутабельными.
