Принципы упаковки программных проектов
В продолжении темы Принципы ООП проектирования хочется продолжить принципами упаковки программных проектов. Взято из Роберт К. Мартин "Быстрая разработка программ. Принципы, примеры, практика".
По мере того, как возрастают размеры и сложность программных проектов, требуется их некоторая высокоуровневая организация. Существует шесть принципов, имеющих к отношение к работе с пакетами. Первые три имеют отношение к сцеплению пакетов. Их применение облегчает выделение классов в пакеты. Остальные три принципа управляют связыванием пакетов. Последние два принципа также описывают набор метрик управления зависимостями. Эти характеристики позволяют разработчикам измерять и характеризовать структуру зависимостей, которая наблюдается в их проектах.
Степень детализации: принципы сцепления пакетов
Принцип эквивалентности повторно применяемых выпусков (REP, Reuse-Release Equivalence Principle)
Уровень детализации повторного применения соотвествует уровню детализации выпуска.
Либо все классы, входящие в состав пакета, являются повторно используемыми, либо ни один из них не входит в эту категорию.
Принцип общего повторного использования (CPR, Common-Reuse Principle)
Классы, входящие в состав пакета, могут повторно использоваться совместно. Если вы можете повторно использовать один из классов, входящих в состав пакета, вам доступны все остальные классы. Совместно используемые классы принадлежат одному пакету, и классы, которые не являются тесно связанными, не относятся к одному пакету.
Принцип общего закрытия (CCP, Common-Closure Principle)
Классы, входящие в состав пакета, должны быть закрыты по отношению к одним и тем же изменениям. Изменение, влияющее на пакет, оказывает воздействие на все классы, входящие в этот пакет (не затрагивая другие пакеты).
Принцип персональной ответственности распространенный на пакеты. Для изменения пакета не должно быть нескольких причин.
Устойчивость: принципы связывания пакетов
Принцип ацикличных зависимостей (ADP, Acyclic-Depending Principle)
Не допускается наличие циклов в графе, описывающем зависимости пакета. Структура пакета «безразлична» к присутствию изменяющихся требований. Естественно, что, по мере поста объема приложений, структура зависимостей пакета «разбухает» и испытывает флуктуации. Именно поэтому структуру зависимостей следует отслеживать на предмет возможного наличия циклов.
Принцип устойчивых зависимостей (SDP, Stable-Dependencies Principle)
Зависит от направления стабильности. Изменчивые пакеты не должны зависеть от пакетов, изменения которых сопряжено со значительными трудностями.
Метрики устойчивости
Один из методов предусматривает подсчет количества зависимостей, которые входят выходят из пакета. Полученные таким образом данные позволяют говорить об оценках позиционной устойчивости пакета.
● (Ca) центростремительное связывание: количество классов вне пакета, которые зависят от классов, образующих пакет.
● (Ce) центробежное связывание: количество классов внутри пакета, которые зависят от классов, не входящих в пакет.
● (I неустойчивость) I = Ce / (Ca + Ce)
Значение метрики попадает в диапазон [0,1]. показатель I = 0 свидетельствует о максимально устойчивом пакете. Показатель I = 1 присущ максимально неустойчивому пакету.
Метрики Ca и Ce определяются путем подсчета количества классов вне данного пакета, которые имею зависимости в классах внутри рассматриваемого пакета. Некоторые программные системы не должны изменяться слишком часто. Эти программы представляют высокоуровневую архитектуру и дизайнерские решения.
Вряд ли мы захотим, чтобы архитектурные решения были изменчивыми. Поэтому программы, представляющие высокоуровневый дизайн системы, должны помещаться в устойчивые пакеты. Неустойчивые пакеты должны включать только те программы, которые должны легко изменяться.
Принцип устойчивости абстракций (SAP, Stable-Abstractions Principle)
Пакет должен быть абстрактным в той же степени, в какой он является устойчивым.
Благодаря применению этого принципа устанавливается взаимосвязь между устойчивостью и абстрактностью. Устойчивые пакеты должны быть также абстрактными, а присущая им устойчивость не предотвращает их возможное расширение. Неустойчивые же пакеты должны быть конкретными.
Оценки абстракций
A-метрика применяется для измерения «степени абстрактности» пакета. Ее значение расчитывается как отношение количества абстрактных классов в пакете к общему количеству классов в пакете.
Nc – количество классов в пакете.
Na – количество абстрактных классов в пакете.
A – мера абстрактности
A = Na / Nc
A-метрика изменяется в диапазоне от 0 до 1. Нулевой показатель означает, что пакет не включает абстрактные классы. Значение равное 1, свидетельствует о том, что пакет состоит исключительно из абстрактных классов.
Главная последовательность
Определим взаимосвязь между устойчивостью (I) и абстрактностью (A). Для этого нарисуем диаграмму, где A представляет ось ординат (по вертикали), а I – ось абсцисс. Если нанести два вида «хороших» пакетов на диаграмму, замечаем, что максимально абстрактные и устойчивые пакеты находятся в верхнем углу (0,1).
Пакеты обладающие максимальной степенью нестабильности и конкурентности, находятся в правом нижнем углу (1,0).
Естественно, что не все пакеты попадают в описанные две категории. Поскольку мы не можем добиться того, чтобы все пакеты попадали в точки с координатами (0,1) и (1,0), остается полагать, что существует область, занимаемая точками на диаграмме A/I, определяющая приемлемые позиции для размещения пакетов. Можно предположить, что эта область определяется зонами, в которых не допускается размещение пакетов.
Рассмотрим пакеты, которые попадают в область с координатами (0,0). Им присуща высокая степень устойчивости и конкретности. И далеко не всегда их применение оправдано из-за присущей им закрепощенности. Причем пакеты не могут расширяться, поскольку не являются абстрактными. А их изменение затруднено в силу характерной для них устойчивости. Поэтому в точке с координатами (0,0) не следует ожидать хорошо спроектированные пакеты.
Болевая зона
Бывают такие ситуации, когда пакеты неизбежно попадают в болевую зону. Например схема БД. Именно схемам БД присуща печально известная изменчивость, беспредельная конкретность, а также высокая степень зависимости. В силу этого реализация интерфейса между OO приложениями и БД является столь непростой, а обновление схем БД затруднены.
Рассмотрим пакет, находящийся в районе точки с координатами (1,1). Эта область нежелательна, поскольку пакету будет присуща максимальная степень абстрактности, причем отсутствуют зависимые от него пакеты. Пользы от подобных пакетов очень мало.
Зона бесполезности
Очевидно, что требуемые нам изменчивые пакеты следует размещать как можно дальше от обеих зон исключения. Область максимального удаления представляет собой прямую, которая соединяет точки (1,0) и (0,1) Хорошие характеристики присущи пакетам, которые находятся либо на главной последовательности, либо возле нее.
Оценка расстояния до главной последовательности
Поскольку желательно, чтобы пакеты находились в области главной последовательности, следует создать метрику, которая измеряет «расстояние от идеала»
D – расстояние
D = |A + I – 1| / sqrt(2)
диапазон изменения находится в области [0,~0,707]
D1 нормализованное расстояние
D1 = |A + I – 1|
Для каждого пакета можно вычислить метрику D. Любой пакет, значение для которого не приближается к нулю, может быть повторно проверен и реструктуризован.
Предостережение
Метрика, описанная здесь, измеряет соответствие проекта "хорошим" образцам зависимости и абстракции. Опыт показал, что некоторые зависимости являются хорошими, а другие плохими. Приведенные образцы отражают тот опыт. Однако, метрика - не бог, а просто измерение на соответствие некоторому стандарту. Для некоторых приложений стандарт будет хорош, для других плох.
Возможно, что имеются лучшие метрики, которые могут использоваться для измерения качества проекта. Таким образом, не стоит решать, что все проекты должны соответствовать метрикам Мартина. Проектировщики должны экспериментировать с этими метриками на своих проектах и оценить их.