Применение принципов чистой архитектуры к корпоративному клиентскому приложению. Часть 0 (Увертюра)

Преамбула

В последнем посте я говорил о различных тонкостях, которые могут возникнуть, если мы не будем осторожны в отделении бизнес-логики приложения от пользовательского интерфейса. Но это был скорее теоретический монолог. На этот раз я хотел бы пойти еще дальше и дать руководство о том, как мы можем достичь этой цели.

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

Соглашения

Фронтенд-разработка, как и любая другая человеческая практика, имеет широкий спектр подходов, техник и даже субъективных предпочтений. Прежде чем мы начнем, я хотел бы дать несколько пояснений о методах и приемах, которые я выбрал для использования в этом руководстве. Это ваше право не соглашаться и отдавать предпочтение другим, но я потрачу несколько абзацев, объясняя свои рассуждения.

Речь идет о создании корпоративного приложения

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

а. имеет довольно много сложности;

б. создается и поддерживается командой разработчиков (не одним и не двумя, а командой);

c. должен оставаться в живых, по крайней мере, несколько лет и быть как можно более независимым от быстрых изменений внешнего интерфейса, с одной стороны, и быть обслуживаемым друг с другом;

d. - это веб-приложение, а не веб-сайт «тонкого клиента», где почти вся бизнес-логика существует на стороне сервера. И это не UI-библиотека, которая, возможно, вообще не содержит бизнес-логики. Я считаю, что для этих случаев более разумным будет другой подход.

Разработка через тестирование

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

Предпосылки

Прежде чем мы начнем, убедитесь, что у вас есть несколько инструментов в вашем наборе инструментов.

Понимание компонентной архитектуры в целом и Vue в частности:

  1. вы знаете, что означает «компонент» с точки зрения пользовательского интерфейса
  2. вы понимаете основной синтаксис Vue
  3. вы знаете, что такое «состояние»
  4. вы знаете, что такое «события рендеринга» и «жизненного цикла»

Понимание Vuex

  1. вы знакомы с рисунком потока
  2. вы знаете, что такое «действия», «мутации» и «магазин»
  3. вы понимаете связь между Vuex и Vue

Объектно-ориентированное программирование

И, что наиболее важно, вы знаете ООП и основные принципы хорошего дизайна программного обеспечения: SOLID, шаблоны проектирования, разделение задач и т. Д. И т. Д. Если вы считаете, что javascript должен поддерживать только функциональное программирование или что « ООП - для разработчиков java », эта статья, вероятно, вас разочарует.

Инструменты

Помимо Vue / Vuex, в наборе инструментов есть пара элементов, которые я собираюсь использовать в этом руководстве:

  1. TypeScript. Мы собираемся запустить корпоративное приложение. Несколько разработчиков будут поддерживать его в течение нескольких лет. Многие разработчики, начавшие проект, будут заменены через несколько лет. Это реальность отрасли. Строгие типы (в сочетании с приличным тестовым покрытием и линтингом) предоставляют отличный способ снизить затраты на обслуживание приложения в долгосрочной перспективе. Я не буду тратить время на то, чтобы убеждать вас, почему это так важно. К счастью, об этом написано сотни и сотни сообщений.
  2. JSX. Vue по умолчанию использует синтаксис шаблона, который субъективно намного более естественен и намного ближе к традиционному HTML, чем JSX. Однако у последнего есть удивительное преимущество: он поддерживает строгие типы. Недавно я опубликовал целый пост о том, почему это важно и как вы можете это использовать.
  3. Шутка. Я собираюсь использовать Jest для модульного тестирования вместе с Vue-test-utils.
  4. Vuetify как Библиотека пользовательского интерфейса

Обзор проекта

Этот проект будет минимизированной, имитирующей версией типичного колоссального корпоративного приложения. Блог довольно часто используется в качестве фиктивного проекта, и я собираюсь следовать этой традиции.

В нашем блоге, естественно, будут статьи, которые пользователи могут читать, и комментарии, которые они могут оставлять. Он будет состоять всего из двух страниц: домашней страницы (содержит короткую версию и ссылки на все статьи) и страницы статьи (полное содержание одной отдельной статьи, комментарии, которые уже были опубликованы людьми, и форма для публикации нового комментария).

К вашим услугам рабочая демка (извините за долгую разминку Heroku)

Исходный код

«Переговоры дешевы, покажи код»

Линус Торвальдс.

Абсолютно согласен, поэтому, если вы не хотите тратить время на дальнейшее чтение, не стесняйтесь прыгать прямо в код

Как пользоваться этим руководством

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

В этой главе мы проанализируем требования, которые мы должны выполнить. Затем мы напишем несколько тестов, чтобы покрыть эти требования, а затем собственно код. И, наконец, мы завершим дополнительные тесты или исправим старые, если это необходимо: с помощью старого доброго TDD.

Сначала проверьте исходный код репо, если вы еще этого не сделали. Затем перейдите в ветку с именем «init». Он вернет репо в исходное состояние с почти пустым проектом. Давайте сначала взглянем на структуру папок.

  • «Сущности», «услуги» и «магазин» будут содержать соответствующие элементы приложения; они пока пусты.
  • Папка «ui» содержит вещи, которые обычно смело помещаются прямо в src: компоненты Vue, страницы маршрутизатора (или представления) и плагины Vue. Мы знаем, что пользовательский интерфейс не важен, поэтому кажется правильным поместить их в специальную подпапку.

Я создаю это приложение на плечах проекта vue-cli. Итак, если вы проверите package.json, вы увидите знакомые команды, такие как «vue-cli-service serve».

Чтобы запустить сервер разработки, просто используйте «npm run serve». Чтобы запустить тесты: «npm t», в режиме часов: «npm run test: watch».

Обратите внимание, что я использую довольно строгие правила ESLint для TypeScript: я применяю явный тип возвращаемого значения функции (кроме выражений и функций высшего порядка), префикс «I» для интерфейсов. Я также запрещаю неиспользуемые переменные и бесполезные конструкторы, точки с запятой и двойные кавычки. Это моя личная (частично субъективная) рекомендация. Вам решать, следовать или игнорировать это в своих реальных проектах.

На каждом шаге каждой главы представлены фрагменты кода. Вы можете скопировать и вставить их, а затем запустить проект. Но я бы рекомендовал вместо этого ввести их. Это поможет вам лучше понять и запомнить этот код и повысить эффективность учебника.

Удачи!

Архитектура

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

На этом рисунке представлено правило зависимости: внутренние кольца ничего не знают о внешних кольцах.

Как видите, в центре вселенной приложения находятся Сущности. Это основные бизнес-правила (или даже бизнес-правила предприятия в более широком случае). Они содержат ценнейшую логику и жизненно важны для приложения - чистые объекты с нулевыми зависимостями.

Следующий круг представляет Услуги. Вы можете рассматривать их как варианты использования для конкретной сущности. Это место, где мы получаем их и манипулируем ими. Сервисы следуют правилу зависимости и зависят только от сущностей.

И, наконец, круг деталей: неважные, дополнительные вещи, такие как UI, DB (или магазин), Frameworks и т. Д. Они зависят от Services и Entities, а также друг от друга (компонент, например, зависит от магазина)

Без лишних слов, вот список тем, которые мы собираемся затронуть:

Увидимся в следующий раз!