Диаграмма пакетов (package diagram) показывает пакеты и зависимости между ними. Я ввел понятие зависимости на стр. 74. При наличии пакетов для классов представления и пакетов для классов предметной области пакет представления зависит от пакета предметной области, если любой класс пакета представления зависит от какого-либо класса пакета предметной области. Таким образом, межпакетная зависимость обобщает зависимости между их содержимым.
В языке UML имеются разнообразные виды зависимостей, каждая из которых обладает самостоятельной семантикой и стереотипом. По моему мнению, намного проще начинать с зависимости без стереотипа и использовать более конкретные виды зависимостей только по мере необходимости. В средних и больших по размеру системах рисование диаграммы пакетов может быть одним из самых ценных приемов, позволяющих управлять их многомерной структурой. В идеале такая диаграмма должна быть сгенерирована на основании собственно исходного кода, так чтобы она реально отражала происходящее в системе.
|
|
Хорошая структура пакетов имеет прозрачный поток (clear flow) зависимостей - концепцию, которую трудно определить, но легко распознать. На рис. 7.2 показана простая диаграмма пакетов для промышленного приложения, которая хорошо структурирована и имеет прозрачный поток зависимостей.
Часто можно идентифицировать прозрачный поток, поскольку все зависимости идут в одном направлении. Это хороший индикатор правильно структурированной системы, но пакеты data mapper (преобразователь данных) на рис. 7.2 представляют исключение из этого эмпирического правила. Пакеты преобразователей данных действуют в качестве изолирующего уровня между пакетами предметной области
(domain) и пакетами базы данных (database) и служат примером шаблона Mapper (Преобразователь) [19].
Многие авторы утверждают, что в зависимостях не должно быть циклов (Acyclic Dependency Principle - принцип ацикличности зависимостей, [30]). Я не считаю это правило абсолютным, но думаю, что циклы необходимо локализовать, в частности не должно быть циклов, пересекающих уровни.
Чем больше зависимостей входит в пакет, тем более стабильным должен быть его интерфейс, поскольку любые изменения интерфейса отразятся на всех пакетах, зависящих от него (Stable Dependencies Principle - принцип стабильных зависимостей, [30]). Поэтому на рис. 7.2 пакету asset domain (предметная область собственности) требуется более стабильный интерфейс, чем пакету leasing data mapper (преобразователь данных аренды). Вы увидите, что зачастую более стабильные пакеты содержат относительно больше интерфейсов и абстрактных классов (Stable Abstractions Principle - принцип стабильных абстракций, [30]).
|
|
Отношения зависимостей не транзитивны (стр. 75). Чтобы убедиться в важности этого свойства для зависимостей, взгляните снова на рис. 7.2. Если изменяется класс пакета предметной области собственности, то может измениться и класс из пакета предметной области аренды (leasing domain). Но эти изменения не обязательно пройдут через представление аренды (leasing presentation). (Они проходят, толь-
ко если предметная область аренды изменяет свой интерфейс.) Некоторые пакеты используются в таком количестве мест, что можно запутаться в линиях зависимостей, идущих к ним. В таком случае действует соглашение, в соответствии с которым на пакете указывается ключевое слово «global» (глобальный).
В пакетах UML определены также конструкции, позволяющие пакетам импортировать классы из одного пакета в другой и объединять их, используя зависимости с ключевыми словами для их обозначения. Однако правила для такого типа элементов существенно отличаются в различных языках программирования. В целом, я думаю, что на практике значительно более полезна основная нотация зависимостей.