Skip to content

Instantly share code, notes, and snippets.

@rtbe
Last active December 16, 2020 16:56
Show Gist options
  • Save rtbe/7b4f0c5be5369c91942656197c91a7fc to your computer and use it in GitHub Desktop.
Save rtbe/7b4f0c5be5369c91942656197c91a7fc to your computer and use it in GitHub Desktop.
Чистая архитектура (Роберт Мартин)

Основные идеи чистой архитектуры

  • Выделение слоёв в архитектуре приложения и соответствующе разделение ответственности между ними (separation of concerns):

    • Высокоуровневые слои описывают общие для всего приложения бизнес правила - политики (policies). Эти слои находятся "внутри" архитектуры приложения.
    • Низкоуровневые слои отвечают за конкретные механизмы и особенности реализаци конкретной функции. Они находятся "снаружи" архитектуры приложения.
  • Правило зависимости (Dependency rule) описывает взаимоотношения между слоями архитектуры приложения. Так высокоуровневые слои внутри приложения не должны зависеть от низкоуровневых слоёв снаружи, то есть бизнес правила приложения не должны быть связаны (coupled) c конкретными механизмами их реализации.

    "We keep these things on the outside where they can do little harm."

    "We don’t want anything in an outer circle to impact the inner circles."

    "Nothing in an inner circle can know anything at all about something in an outer circle. In particular, the name of something declared in an outer circle must not be mentioned by the code in the an inner circle. That includes, functions, classes. variables, or any other named software entity". By the same token, data formats used in an outer circle should not be used by an inner circle, especially if those formats are generate by a framework in an outer circle." - Robert C. Martin

В одноименной статье Роберт Мартин выделяет следующие слои архитектуры приложения:

  • Сущности (Entities) - описывают общие для всего приложения правила (enterprise wide business rules). Сущностями могут являться объекты прикладной сферы приложения, например книгой в библиотеке или поситителем библиотеки который её взял. Сущности задействуются в различных процессах приложения. Выделение этого слоя защищает общие правила приложения от вмешательства извне. Ты не ожидаешь, что на эти правила окажут влияние изменения в деталях работы приложения (смена базы данных, смена фреймворка, смена роутинга для обработки сетевых запросов и так далее). Никакие изменения извне не должны влиять на этот слой архитектуры приложения.
  • Случаи использования (Use cases) - описывают правила по которым работают отдельные процессы приложения, другими словами это слой отвечающий за бизнес-правила приложения. Данный слой описывает конкретные сценарии использования приложения, организует поток данных к сущностям/от сущностей, что позволяет достичь цели конкретного сценария использования приложения. Ты не ожидаешь, что изменения в бизнес логике могут повлиять на сущности, которые в них задействованы. Так же на этот слой не должны влиять и изменения в конкретных деталях реализации этого процесса. Но изменения в данном слое неизбежно окажут влияние, на детали его реализации.
  • Адаптеры/интерфейсы - данный слой служит набором адаптеров, которые осуществляют перевод данных из формата наиболее удобного для работы на уровне сущностей/случаев их использования в формат наиболее удобный для осуществления конкретной функции (Пример: Перенос сущности для её сохранения в базе данных). Другими словами код внутри этого слоя, не должен ничего знать о базе данных, и конкретном формате данных с которым она работает, этот слой - переводчик с обобщенного языка сущностей и сценариев их использования на язык конкретной реализации соответствующей функции и наоборот (с языка конкретной реализации, на язык сценариев использования сущностей).
  • Фреймворки/драйверы - самый внешний слой во всей архитектуре, содержащий низкоуровневые детали реализации. В нем находится набор инструментов для реализации процессов приложения. Данный слой хранит в себе все механизмы и детали, которые можно поменять - сменить один фреймворк/библиотеку/базу данных на другую, при необходимости.

Пример чистой архитектуры в реальной жизни

Стэк TCP/IP или OSI model

Архитектура сетевого взаимодействия разделена на слои, начиная от самого абстрактного(высокоуровнего) - прикладном/приложений, где описываются соответствующие протоколы т.е наборы правил для взамодействия приложений в сети. Заканчивая самым конкретным (низкоуровневым) - физическим, который отвечает за конкретную передачу физических сигналов по различным каналам связи (различным видам проводов/воздуху).

В модели OSI на самом абстрактном уровне - уровне приложения не описаны конкретные детали реализации сетевого взаимодействия (как будет упаковано сообщение, каким образом оно будет доставлено получателю, как сообщение будет передано в виде набора физических сигналов по сети и так далее). А описан набор общих правил - протоколов (http,https, ftp) общения между приложениями. Данный слой взаимодействует с слоем ниже (транспортным) с помощью специального механизма - сокетов (в случае протокола http - TCP(stream) сокеты).

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

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

Другими словами в OSI или TCP/IP модели реализован принцип инверсии зависимости ("D" в SOLID). Реализация этого принципа обеспечила гибкость сетевой архитектуре, что проявилось в способности адаптироваться данной модели к постоянно меняющимся требованиям к сетевому взаимодействию. Так по мере развития интернета развиваются и соответствующие протоколы - например развитие протокола http с его множеством версий (1.0/1.1/2.0/3.0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment