Проблемы, что мы обсудили к данному моменту, ведут к однозначному заключению: структура компонентов не может проектироваться сверху вниз. К этому выводу приходят не сразу, как только начинают проектировать систему, но это неизбежно случается с ростом и изменением системы.
Некоторые читатели могут счесть это утверждение нелогичным. Мы обычно ожидаем, что разложение на крупные составляющие, такие как компоненты, будет также соответствовать разложению по
Рассматривая крупноблочную диаграмму, такую как структура зависимостей компонентов, мы полагаем, что компоненты должны каким-то образом представлять функции системы. Но в действительности это не является непременным атрибутом диаграмм зависимостей компонентов.
Фактически диаграммы зависимостей компонентов слабо отражают функции приложения. В большей степени они являются отражением
Одной из главных задач такой структуры зависимостей является изоляция изменчивости. Нам не нужны компоненты, часто изменяющиеся по самым мелким причинам и влияющие на другие компоненты, которые иначе были бы вполне стабильными. Например, косметические изменения в графическом интерфейсе не должны влиять на бизнес-правила. Добавление и изменение отчетов не должно влиять на высокоуровневые политики. Следовательно, граф зависимостей компонентов создается и формируется архитекторами для защиты стабильных и ценных компонентов от влияния изменчивых компонентов.
По мере развития приложения мы начинаем беспокоиться о создании элементов многократного пользования. На этом этапе на состав компонентов начинает влиять принцип совместного повторного использования (CRP). Наконец, с появлением циклов мы начинаем применять принцип ацикличности зависимостей (ADP), в результате начинает изменяться и разрастаться граф зависимостей компонентов.
Попытка спроектировать структуру зависимостей компонентов раньше любых классов, скорее всего, потерпит неудачу. На этом этапе мы почти ничего не знаем о согласовании изменений, не представляем, какие элементы можно использовать многократно и почти наверняка создадим компоненты, образующие циклические зависимости. Поэтому структура зависимостей компонентов должна расти и развиваться вместе с логическим дизайном системы.
Принцип устойчивых зависимостей
Зависимости должны быть направлены в сторону устойчивости.
Дизайн не может оставаться статичным. Некоторая изменчивость все равно необходима, если предполагается сопровождать дизайн. Следуя принципу согласованного изменения (CCP), мы создаем компоненты, чувствительные к одним изменениям и невосприимчивые к другим. Некоторые из компонентов
Компоненты, с большим трудом поддающиеся изменению, не должны зависеть от любых изменчивых компонентов. Иначе изменчивый компонент тоже трудно будет изменять.
Это одна из превратностей программного обеспечения, когда модуль, проектировавшийся специально, чтобы упростить возможность изменений, становится сложно изменять просто из-за того, что от него зависит другой модуль. Представьте: вы не изменили ни строчки кода в своем модуле, и вдруг его стало сложно изменять. Следуя принципу устойчивых зависимостей (Stable Dependencies Principle; SDP), мы гарантируем, что модули, с трудом поддающиеся изменению, не будут зависеть от модулей, спроектированных для упрощения изменений.
Устойчивость
Что подразумевается под «устойчивостью»? Представьте себе монету, стоящую на ребре. Является ли такое ее положение устойчивым? Скорее всего, вы ответите «нет». Однако если оградить ее от вибраций и дуновений ветра, она может оставаться в таком положении сколь угодно долго. То есть устойчивость напрямую не связана с частотой изменений. Монета не изменяется, но едва ли кто-то скажет, что, стоя на ребре, она находится в устойчивом положении.