Monday, January 27, 2020

"Чистая архитектура" Роберта Мартина. Кратчайший конспект книги

Архитектура = дизайн.

Архитектура включает в себя функциональную и структурную составляющие.

Знания о хорошей архитектуре в основном - правила как не надо делать.

Парадигмы программирования

Структурное программирование Дейкстры - отказ от оператора GOTO или прямой передачи управления в коде.

ООП появилось с возможностью помещать часть стека вызова функции (вместе с локальными переменными) и указателей функций в "кучу" памяти. Так родились конструкторы и методы классов.

Инкапсуляция была возможно ещё и в не ОО-языках. Но в книге инкапсуляция отождествяется с сокрытием данных, с этим категорически не согласен. Это то же самое, что говорить SSL = TLS. Как по мне, инкапсуляция - отсутствие возможности обращаться к данным и функциям "объекта" напрямую из памяти, минуя ссылку на сам объект. При этом все данные могут быть доступны всем, у кого есть ссылка на объект.

Наследование тоже не новинка ООП.

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

SOLID принципы

Single Responsibility Principle - у модуля/класса/.. должна быть одна и только одна причина для изменения => модуль должен отвечать за одного и только одного пользователя => модуль должен отвечать только за одного и только одного актора.

Признаки нарушения принципа: 1) непреднамеренное дублирование; 2) слияния (мержи).

Open-closed principle 
Достигается делением системы на компоненты и упорядочением их зависимостей в иерархию, защищающую компоненты уровнем выше от изменений в компонентах уровнем ниже.

Принцип подстановки Барбары Лисков
Если для каждого объекта типа S существует такой объект типа T, что для всех программ P, определённых в терминах T, поведение P не изменяется при подстановке объекта S вместо T, то S является подтипом T.

Принцип можно использовать при создании иерархии наследования.

Проблема "квадрат/прямоугольник"

Interface Segregation Principle 
Актуален для статических языков программирования, т.е является проблемой языка, а не архитектуры.
Опасно создавать зависимости от модулей, содержащих больше, чем требуется.

Dependency Inversion Principle
Интерфейсы стабильнее конкретных реализаций, менее изменчивы. Наследование - самый жесткий тип отношения в исходном коде. Почему "принцип инверсии зависимости"? - "Архитектурная" линия пересекает диаграммы компонент/классов так, что "поток управления" обращён относительно зависимостей исходного кода.

Полностью устранить все нарушения невозможно, но их можно сосредоточить в узком месте и изолировать от остальной системы.

////////////////////////

Связность компонентов

Reuse/release Equivalence Principle
Common Closure Principle - аналог SRP для компонентов.
Common Reuse Principle - аналог ISP для компонентов - классы, не имеющие тесной связи, не должны включаться в один компонент. Не создавайте зависимостей от чего-либо неиспользуемого.

Первые два принципа являются включительными, а третий исключительным, стремящимся сделать компоненты как можно мельче.

Сочетаемость компонентов

Принцип ацикличности зависимостей (еженедельные сборки и устранение циклических зависимостей). "Зацикленный" набор компонент превращается в один большой компонент.

Как разорвать цикл: 1) инверсия зависимостей; 2) создание нового компонента.

Принцип устойчивых зависимостей - зависимости должны быть направлены в сторону устойчивости. Метрика стабильности ( Fan-out/(Fan-in + Fan-out) ) должна уменьшаться в направлении зависимости.

Принцип устойчивости абстракций - устойчивость компонента пропорциональна его абстрактности.


Что такое архитектура

Предназначение архитектуры - поддержка жизненного цикла системы. Как можно дольше иметь как можно больше вариантов.

Разработка, развёртывание, эффективность работы, сопровождение, сохранение разнообразия вариантов.

Закон Конвея:
Любая организация, разрабатывающая систему, невольно будет формировать дизайн, структура которого повторяет структуру взаимодействий внутри этой организации.

Скромный объект (Humble object)

Разделить поведение на два модуля, один из которых содержит всё, что с трудом поддаётся тестированию, код в этом объекте упрощается до предела - это скромный объект.

Шлюзы к базам данных
Преобразователи данных (ORM)

Неполные границы

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

База данных - это деталь

Организационная структура и модель данных являются архитектурно значимыми, а технологии и системы, перемещающие данные на магнитную поверхность - нет.