
Для разработчиков приложений Flutter - простой способ разобраться в чистой архитектуре приложений Flutter.
Заявление об ограничении ответственности
Роберт Мартин - засранец. Я не оправдываю его мерзких поступков по отношению к женщинам. Это статья о концепциях Clean Arch, представленных в его книге «Чистый код». Если вы не можете уважать пол, который дал вам жизнь, тогда какой вы, черт возьми, человек?
Фон
Хотя многоуровневая архитектура Onion занимается тем, как данные связаны с другими уровнями; общий дизайн архитектуры приложения - это то, на чем сосредоточена чистая архитектура. Впервые она была представлена как полная архитектура приложения в книге Роберта Мартина «Чистый код» и далее доработана в его книге «Чистая архитектура».
Характеристики чистой арки
Вот как выглядит типичное приложение флаттера, включая приложение шаблона счетчика флаттера по умолчанию, которое создается при создании нового проекта:

Попробуйте заменить ножницы ручкой? В коде в приложении счетчика шаблона Flutter структура данных счетчика и модель объединены в один класс MyHomePage экрана пользовательского интерфейса Flutter.
Это означает, что у вас нет настроенных слоев, в которых можно было бы реализовать элементы управления для управления как событиями между уровнями, так и состоянием модели представления и состоянием приложения.
Если мы разделим слои, то получим что-то вроде этого, где мы можем легко заменить один объект другим:

Вы начинаете с двух слоев:

БОКОВОЕ ПРИМЕЧАНИЕ: Eagle - это первое пошаговое приложение для флаттера, которое я создаю, чтобы показать дизайнерам и кодировщикам, как реализовать код и разрабатывать приложения для флаттера, и оно использует GraphQL для доступа к данным GitHub и отображения их как для репозиториев GitHub, так и для Пользователи GitHub. Первые два шага - разделить два первых уровня чистой архитектуры, и оба шага находятся в подпапке eagle кода с репозиторием GitHub:
Первым шагом является настройка двух уровней инфраструктуры, инициализации приложения и пользовательского интерфейса:
Главный:
Мое приложение:
Моя домашняя страница:
Второй шаг - настроить уровень домена:
Миксин модели представления:
И модификации MyHomepage для вызова методов миксина:
Историческая справка об архитектуре приложений xVM
Архитектуры приложений xVM являются подмножеством чистой архитектуры и связаны с уровнями домена и инфраструктуры. Исторически сложилось так, что сначала все было напрямую связано, что доставляло кошмарные головные боли, и лишь недавно перешло на слабо связанную архитектуру подмножества. Мы называем это аркой xVM, поскольку теперь она сосредоточена на наилучшей возможной модели представления.
Определение внутренних слоев
Теперь нам нужно определить некоторые внутренние слои:

Теперь мы должны определить объекты домена и адаптеры. Давайте снова посмотрим CounterStoreMixin:
Счетчик должен быть выделен как отдельный объект домена. Этот объект домена должен инкапсулировать бизнес-правило. В данном случае это счетчик, начинающийся с нуля при запуске приложения.
Если мы используем только это приложение-счетчик в качестве примера, адаптирующая часть данных для варианта использования не имеет значения, поскольку у нас еще недостаточно сложности в модели для более сложных и многочисленных вариантов использования.
Прямо сейчас у нас есть только два варианта использования; счетчик начинается с нуля при запуске приложения и увеличивается на единицу. Поскольку это простое поведение может быть полностью инкапсулировано в модель представления, нам не нужно добавлять адаптеры данных вариантов использования.
Вкратце, адаптеры взаимодействуют с уровнем данных, чтобы транслировать бизнес-правила в инфраструктуру пользовательского интерфейса, принимать вводимые пользователем данные и транслировать их в специфику уровня домена.
Принципы реализации чистой архитектуры
Это принципы, которые я использую не только для определения уровней домена и инфраструктуры, но также адаптеров и уровней обслуживания.
Принцип единой ответственности (SRP)
Это буква S SOLID. SRP говорит, что у класса должна быть только одна работа. У него может быть несколько методов, но все они работают вместе, чтобы делать одно главное. У класса должна быть только одна причина для изменения. Например, если у финансового управления есть одно требование, которое изменит класс, а у отдела кадров есть требование, которое изменит класс по-другому, тогда есть две причины для изменения. Класс следует разделить на два отдельных класса, у каждого из которых есть только одна причина для изменения.
Принцип открытости-закрытости (OCP)
Это буква O SOLID. Открытый означает открытый для расширения. Закрыто означает закрыто для модификации. Таким образом, вы должны иметь возможность добавлять функциональные возможности к классу или компоненту, но вам не нужно изменять существующие функциональные возможности. Как ты это делаешь? Вы убедитесь, что каждый класс или компонент несет только одну ответственность, а затем вы скрываете более стабильные классы за интерфейсами, чтобы на них не повлияло изменение менее стабильных классов.
Принцип замещения Лискова (LSP)
Это буква L SOLID. Я предполагаю, что им нужна была буква L для написания SOLID, но «подстановка» - это все, что вам нужно запомнить. Этот принцип означает, что классы или компоненты более низкого уровня могут быть заменены, не влияя на поведение классов и компонентов более высокого уровня. Это можно сделать, реализовав абстрактные классы или интерфейсы. Например, в Java и ArrayList, и LinkedList реализуют интерфейс List, поэтому их можно заменять друг на друга. Если бы этот принцип применялся на уровне архитектуры, MySQL можно было бы заменить на MongoDB, не затрагивая логику предметной области.
Принцип разделения интерфейса (ISP)
Это - Я ТВЕРДЫХ. ISP относится к использованию интерфейса для отделения класса от других классов, которые его используют. Интерфейс предоставляет только то подмножество методов, которое требуется зависимому классу. Таким образом, когда есть изменения в других методах, они не влияют на зависимый класс.
Принцип инверсии зависимостей (DIP)
Это буква D SOLID. Это означает, что менее стабильные классы и компоненты должны зависеть от более стабильных, а не наоборот. Если стабильный класс зависит от нестабильного класса, то каждый раз, когда нестабильный класс изменяется, это также влияет на стабильный класс. Таким образом, необходимо изменить направление зависимости. Как это сделать? Используя абстрактный класс или скрывая стабильный класс за интерфейсом.
Принцип эквивалентности повторного использования / выпуска (REP)
REP - это принцип на уровне компонентов. Повторное использование относится к группе повторно используемых классов или модулей. Релиз - это публикация с номером версии. Этот принцип гласит, что все, что вы выпускаете, следует повторно использовать как единое целое. Это не должен быть случайный набор несвязанных классов.
Общий принцип закрытия (CCP)
CCP - принцип компонентного уровня. В нем говорится, что компоненты должны представлять собой набор классов, которые изменяются по одной и той же причине в одно и то же время. Если есть разные причины для изменения или классы меняются с разной скоростью, то компонент следует разделить. По сути, это то же самое, что и приведенный выше принцип единой ответственности.
Общий принцип повторного использования (CRP)
CRP - это принцип компонентного уровня. Он говорит, что вы не должны зависеть от компонента, у которого есть классы, которые вам не нужны. Эти компоненты следует разделить, чтобы пользователям не приходилось зависеть от классов, которые они не используют. По сути, это то же самое, что и принцип разделения интерфейса, описанный выше.
Эти три принципа (REP, CCP и CRP) противоречат друг другу. Слишком сильное разделение или слишком большое количество группировок могут вызвать проблемы. Необходимо сбалансировать эти принципы в зависимости от ситуации.
Принцип ациклической зависимости (ADP)
ADP означает, что в вашем проекте не должно быть циклов зависимости. Например, если компонент A зависит от компонента B, а компонент B зависит от компонента C, а компонент C зависит от компонента A, то у вас есть цикл зависимости.
Наличие такого цикла создает серьезные проблемы при попытке внести изменения в систему. Одно из решений разорвать цикл - использовать принцип инверсии зависимостей и добавить интерфейс между компонентами. Если разные люди или группы несут ответственность за разные компоненты, то компоненты должны выпускаться индивидуально с их собственными номерами версий. Таким образом, изменения в одном компоненте не обязательно сразу повлияют на другие команды.
Принцип стабильной зависимости (SDP)
Этот принцип гласит, что зависимости должны быть в направлении стабильности. То есть менее стабильные компоненты должны зависеть от более стабильных компонентов. Это сводит к минимуму эффект изменения. Некоторые компоненты являются летучими. Это нормально, но не стоит делать стабильные компоненты зависимыми от них.
Принцип стабильной абстракции (SAP)
SAP утверждает, что чем более стабильным является компонент, тем более абстрактным он должен быть, то есть тем более абстрактных классов он должен содержать. Абстрактные классы легче расширять, поэтому стабильные компоненты не становятся слишком жесткими.
Заключение
Это в некотором роде набросок этапов реализации кода, которые я прохожу при создании приложения для флаттера под названием Eagle. И я разбил его так, чтобы вы могли видеть шаги, по одному небольшому набору за раз, в этом репозитории кода:
Обо мне, Фред Гротт
Я реформированный разработчик Android, Java, Kotlin и Front-End; и возрожденный СДВГ, Дизайнер и Создатель.
Самое забавное в разработке и дизайне Front-End приложений то, что мы программируем людей, а не компьютеры. Это не кодирование или дизайн сами по себе; но кодирование и дизайн, стремящиеся с помощью своих артефактов, создают историю, чтобы схватить человека и сказать: сделай это!
Я участвую в нескольких плагинах сообщества Flutter, включая:
Виджеты платформы Flutter
Https://pub.dev/packages/flutter_platform_widgets
Ловец
Https://pub.dev/packages/catcher
Некоторые из моих полезных статей и руководств:
UI
Декларативные наложения
Https://medium.com/p/declarative-overlays-1c4f744d1c6e
Потрясающий OnBoarding https://medium.com/p/awesome-onboarding-6b61a1d077ef
Google Fonts, правильный путь https://medium.com/p/google-fonts-the-right-way-72a715f046a3
DevOPS
Легкое издевательство с моктейлем
Https://medium.com/p/easy-mocking-with-mocktail-f3fd10a1eecd
Тестирование виджетов BDD Like
Https://medium.com/p/bdd-like-widget-testing-bb95b12edac7
Экспертный способ использования золотых монет
Https://medium.com/p/expert-way-to-use-goldens-45b46aa8e2c3
Мнения по установке Flutter SDK https://medium.com/p/an-opinionated-way-to-install-the-flutter-sdk-cca997967192
Легкое создание UML
Https://medium.com/p/easy-uml-generation-e6e16e5c8b0a
Супер секретная ловушка для флаттера
Https://medium.com/geekculture/super-secret-bug-trap-for-flutter-c89d36974b96
Моя экспертная установка проекта, многоуровневая луковая архитектура
Https://medium.com/geekculture/my-expert-project-setup-layered-onion-architecture-5dd06e29ee9f
Идеальная настройка Flutter
Https://medium.com/codex/flutter-perfect-setup-c5462b412f78
Настройка Flutter Expert IDE
Https://medium.com/geekculture/flutter-expert-ide-set-up-25791ce690c
Установка Expert Catcher для приложений Flutter
Https://medium.com/p/expert-catcher-setup-for-flutter-apps-a9ee3a6a9e08
ООП и ФП
Что, черт возьми, такое государственное управление
Https://medium.com/p/what-the-hell-is-state-management-ee49559e6f48
Антипаттерны государства
Https://medium.com/p/anitpatterns-of-state-610dae657ac6
Тренировочные колеса для реактивного флаттера
Https://medium.com/p/training-wheels-for-reactive-flutter-d1ae35c47787
Глубокое погружение в состояние
Https://medium.com/geekculture/deep-dive-into-state-34b443da3573
Выбор решения для управления состоянием флаттера https://medium.com/p/choosing-a-flutter-state-management-solution-cccf1b2acf10
Жизнь
Как я научился доверять своему СДВГ
Https://medium.com/p/how-i-learned-to-trust-my-adhd-dbf4f80518cc
Диетическая кока-кола вызвала у этого разработчика СДВГ
Https://medium.com/p/diet-coke-gave-hits-developer-adhd-cd4d7f3f73cd
Некоторые места, где можно подписаться на меня:
Https://www.xing.com/profile/Fred_Grott/cv
Https://www.linkedin.com/in/fredgrottstartupfluttermobileappdesigner/
Создавай и твори для жизни….