Области видимости и действия, кратность и иерархия классов
Одна из деталей, наиболее существенных для атрибутов и операций классификаторов, – их видимость. Видимость свойства говорит о том, может ли оно использоваться другими классификаторами. Естественно, это подразумевает видимость самого классификатора. Один классификатор может "видеть" другой, если тот находится в области действия первого и между ними существует явное или неявное отношение. В языке UML можно определить три уровня видимости:
public (открытый) – любой внешний классификатор, который "видит" данный, может пользоваться его открытыми свойствами. Обозначается знаком + (плюс) перед именем атрибута или операции;
protected (защищенный) – любой потомок данного классификатора может пользоваться его защищенными свойствами. Обозначается знаком # (диез);
private (закрытый) – только данный классификатор может пользоваться закрытыми свойствами. Обозначается символом – (минус).
На рис. 6.82. показаны открытые, защищенные и закрытые атрибуты и методы для класса Toolbar.
Рис. 6.82. Видимость
Видимость свойств классификатора определяют для того, чтобы скрыть детали его реализации и показать только те особенности, которые необходимы для осуществления обязанностей, продекларированных абстракцией. Если символ видимости явно не указан, обычно предполагается, что свойство является открытым. Отношения дружественности (Friendship) позволяют классификатору показывать другим свои закрытые детали.
Еще одной важной характеристикой атрибутов и операций классификатора является область действия (Scope). Задавая область действия некоторого свойства, тем самым указывают, будет ли оно проявлять себя по–разному в каждом экземпляре классификатора, или одно и то же значение свойства будет разделяться (то есть совместно использоваться) всеми экземплярами. В UML определены два вида областей действия:
instance (экземпляр) – у каждого экземпляра классификатора есть собственное значение данного свойства;
classifier (классификатор) – все экземпляры классификатора совместно используют общее значение данного свойства.
Имя свойства, которое имеет область действия classifier, подчеркивается. Если подчеркивание отсутствует, предполагается область действия instance. Как правило, свойства моделируемых классификаторов имеют область действия экземпляра. Свойства с областью действия классификатора чаще всего применяются для описания закрытых атрибутов, общих для всех экземпляров, например для генерации уникальных идентификаторов или в операциях, создающих экземпляры класса.
При моделировании иерархии классов, верхние уровни занимают общие абстракции, а ниже находятся специализированные классы. Внутри этой иерархии некоторые классы определяют как абстрактные, то есть не имеющие непосредственных экземпляров. В языке UML имя абстрактного класса пишут курсивом. Наоборот, конкретными называются классы, которые могут иметь непосредственные экземпляры.
При моделировании класса часто возникает потребность задать ему свойства, унаследованные от более общих классов и, наоборот, предоставить возможность более специализированным классам наследовать особенности данного. Такая семантика легко обеспечивается для классов средствами UML. Можно определить и такие классы, у которых нет потомков. Они называются листовыми и задаются в UML с помощью свойства leaf (лист), написанного под именем класса.
Реже используется возможность задать класс, не имеющий родителей. Такой класс называется корневым и специфицируется с помощью свойства root (узел), записанного под его именем. Если имеется несколько независимых иерархий наследования, то начало каждой удобно обозначать таким способом.
Операции могут иметь сходные свойства. Как правило, операции являются полиморфными, – это значит, что в различных местах иерархии классов можно определять операции с одинаковыми сигнатурами. При этом те операции, которые определены в классе–потомке, перекрывают действие тех, что определены в родительских классах. Когда во время исполнения системы поступает какое–то сообщение, операция по его обработке вызывается полиморфно, – иными словами, выбирается та, которая соответствует типу объекта. В UML имена абстрактных операций пишутся курсивом, как и в случае с классами. Не полиморфные операции (листовые) обозначаются при помощи слова leaf. Это означает, что данная операция не может быть перекрыта другой.
При работе с классом разумно предположить, что может существовать любое количество его экземпляров – если, конечно, это не абстрактный класс, у которого вообще не существует непосредственных экземпляров, хотя у его потомков их может быть любое количество. В некоторых случаях, однако, число экземпляров класса нужно ограничить. Чаще всего возникает необходимость задать класс, у которого:
нет ни одного экземпляра – тогда класс становится служебным (Utility), содержащим только атрибуты и операции с областью действия класса;
ровно один экземпляр – такой класс называют одиночным (Singleton);
заданное число экземпляров;
произвольное число экземпляров – вариант по умолчанию.
Количество экземпляров класса называется его кратностью. В общем смысле кратность – это диапазон возможных кардинальных чисел некоторой сущности. В языке UML кратность класса задается выражением, написанным в правом верхнем углу его пиктограммы. Кратность применима и к атрибутам. Кратность атрибута записывают в виде выражения, заключенного в квадратные скобки и расположенного сразу после имени атрибута. Например, как показано на рис. 6.83.
Рис. 6.83. Кратность
Таким образом, на самом высоком уровне абстракции, моделируя структурные свойства класса (то есть атрибуты), можно просто записать их имена. В дополнение к этому, можно определить видимость, область действия и кратность каждого атрибута. Кроме того, можно задать тип, начальное значение и изменяемость атрибутов. А для обозначения множества логически связанных атрибутов допустимо использовать стереотипы.
В UML определены четыре стандартных стереотипа, применимые к классам:
metaclass – определяет классификатор, все объекты которого являются классами;
powertype – определяет классификатор, все объекты которого являются потомками данного родителя;
stereotype – определяет, что данный классификатор является стереотипом, который можно применить к другим элементам;
utility – определяет класс, атрибуты и операции которого находятся в области действия всех классов.
Суммируя сказанное, получаем, что хорошо структурированный классификатор обладает следующими свойствами:
наделен как структурными, так и поведенческими аспектами;
внутренне согласован и слабо связан с другими классификаторами;
раскрывает только те особенности, которые необходимы для, использующих класс клиентов, и скрывает остальные;
его семантика и назначение не допускают неоднозначного толкования;
не настолько формализован, чтобы лишить всякой свободы тех, кто будет его реализовывать;
специфицирован в достаточной степени, чтобы исключить неоднозначное толкование его назначения.
Изображая классификатор в UML, принимают во внимание следующие рекомендации:
показывать только те его свойства, которые необходимы для понимания абстракции в контексте класса;
использовать такие стереотипы, которые наилучшим образом отражают назначение классификатора.
Отношения между классами
Кроме внутреннего устройства классов важную роль при разработке проектируемой системы имеют различные отношения между классами, которые также могут быть изображены на диаграмме классов. Совокупность допустимых типов таких отношений строго фиксирована в языке UML и определяется самой семантикой этих отношений. Базовые отношения, изображаемые на диаграммах классов:
Отношение ассоциации (Association relationship)
Отношение обобщения (Generalization relationship)
Отношение агрегации (Aggregation relationship)
Отношение композиции (Composition relationship)
Каждое из этих отношений имеет собственное графическое представление, которое отражает семантический характер взаимосвязи между объектами соответствующих классов.
Отношение ассоциации
Ассоциация (Association) – семантическое отношение между двумя и более классами, которое специфицирует характер связи между соответствующими экземплярами этих классов.
Отношение ассоциации соответствует наличию произвольного отношения или взаимосвязи между классами. Данное отношение, как уже отмечалось, обозначается сплошной линией со стрелкой или без нее и с дополнительными символами, которые характеризуют специальные свойства ассоциации. Ассоциации рассматривались при изучении элементов диаграммы вариантов использования, применительно к диаграммам классов, тем не менее, семантика этого типа отношений значительно шире. В качестве дополнительных специальных символов могут использоваться имя ассоциации, символ навигации, а также имена и кратность классов–ролей ассоциации.
Имя ассоциации – необязательный элемент ее обозначения. Однако если оно задано, то записывается с заглавной буквы рядом с линией ассоциации. Отдельные классы ассоциации могут играть определенную роль в соответствующем отношении, на что явно указывает имя концевых точек ассоциации на диаграмме.
Наиболее простой случай данного отношения – бинарная ассоциация (Binary association), которая служит для представления произвольного отношения между двумя классами. Она связывает в точности два различных класса и может быть ненаправленным (симметричным) или направленным отношением. Частный случай бинарной ассоциации – рефлексивная ассоциация, которая связывает класс с самим собой. Ненаправленная бинарная ассоциация изображается линией без стрелки. Для нее на диаграмме может быть указан порядок чтения классов с использованием значка в форме треугольника рядом с именем данной ассоциации.
В качестве простого примера ненаправленной бинарной ассоциации можно рассмотреть отношение между двумя классами – классом Компания и классом Сотрудник (рис. 6.84.). Они связаны между собой бинарной ассоциацией Работает, имя которой указано на рисунке рядом с линией ассоциации. Для данного отношения определен следующий порядок чтения следования классов – сотрудник работает в компании.
Рис. 6.84. Графическое изображение ненаправленной бинарной ассоциации между классами
Направленная бинарная ассоциация изображается сплошной линией с простой стрелкой на одной из ее концевых точек. Направление этой стрелки указывает на то, какой класс является первым, а какой – вторым.
В качестве простого примера направленной бинарной ассоциации можно рассмотреть отношение между двумя классами – классом Клиент и классом Счет (рис. 6.85.). Они связаны между собой бинарной ассоциацией с именем Имеет, для которой определен порядок следования классов. Это означает, что конкретный объект класса Клиент всегда должен указываться первым при рассмотрении взаимосвязи с объектом класса Счет. Другими словами, эти объекты классов образуют кортеж элементов, например, <клиент, счет_1, счет_2,…, счет_n>.
Рис. 6.85. Графическое изображение направленной бинарной ассоциации между классами
Частный случай отношения ассоциации – так называемая исключающая ассоциация (Xor–association). Семантика данной ассоциации указывает на то, что из нескольких потенциально возможных вариантов данной ассоциации в каждый момент времени может использоваться только один. На диаграмме классов исключающая ассоциация изображается пунктирной линией, соединяющей две и более ассоциации (рис. 6.86.), рядом с которой записывается ограничение в форме строки текста в фигурных скобках: {xor}.
Рис. 6.86. Графическое изображение исключающей ассоциации между тремя классами
Тернарная ассоциация связывает отношением три класса. Ассоциация более высокой арности называется n–арной ассоциацией.
n–арная ассоциация (n–ary association) – ассоциация между тремя и большим числом классов.
Каждый экземпляр такой ассоциации представляет собой упорядоченный набор (кортеж), содержащий n экземпляров из соответствующих классов. Такая ассоциация связывает отношением более чем три класса, при этом класс может участвовать в ассоциации более чем один раз. Каждый экземпляр n–арной ассоциации представляет собой n–арный кортеж, состоящий из объектов соответствующих классов. В этом контексте бинарная ассоциация является частным случаем n–арной ассоциации, когда значение n=2, но имеет собственное обозначение. Бинарная ассоциация – это специальный случай n–арной ассоциации.
Графически n–арная ассоциация обозначается ромбом, от которого ведут линии к символам классов данной ассоциации. Сам же ромб соединяется с символами классов сплошными линиями. Обычно линии проводятся от вершин ромба или от середины его сторон. Имя n–арной ассоциации записывается рядом с ромбом соответствующей ассоциации. Однако порядок классов в n–арной ассоциации, в отличие от порядка множеств в отношении, на диаграмме не фиксируется.
В качестве примера тернарной ассоциации можно рассмотреть отношение между тремя классами: Сотрудник, Компания и Проект. Данная ассоциация указывает на наличие отношения между этими тремя классами, которое может представлять информацию о проектах, реализуемых в компании, и о сотрудниках, участвующих в выполнении отдельных проектов (рис. 6.87.).
Рис. 6.87. Графическое изображение тернарной ассоциации между тремя классами
Класс может быть присоединен к линии ассоциации пунктирной линией. Это означает, что данный класс обеспечивает поддержку свойств соответствующей n–арной ассоциации, а сама n–арная ассоциация имеет атрибуты, операции и/или ассоциации. Другими словами, такая ассоциация является классом с соответствующим обозначением в виде прямоугольника и самостоятельным элементом языка UML – ассоциацией классом (Association class).
Ассоциация–класс (Association class) – модельный элемент, который одновременно является ассоциацией и классом. Ассоциация класс может рассматриваться как ассоциация, которая обладает свойствами класса, или как класс, имеющий также свойства ассоциации.
Как уже упоминалось, отдельный класс в ассоциации может играть определенную роль в данной ассоциации. Эта роль может быть явно специфицирована на диаграмме классов. С этой целью в языке UML вводится в рассмотрение специальный элемент – концевая точка ассоциации или конец ассоциации (Association end), который графически соответствует точке соединения линии ассоциации с отдельным классом.
Конец ассоциации (Association end) – концевая точка ассоциации, которая связывает ассоциацию с классификатором.
Конец ассоциации – часть ассоциации, но не класса. Каждая ассоциация может иметь два или больше концов ассоциации. Наиболее важные свойства ассоциации указываются на диаграмме рядом с этими элементами ассоциации и должны перемещаться вместе с ними. Одним из таких дополнительных обозначений является имя роли отдельного класса, входящего в ассоциацию.
Роль (Role) – имеющее имя специфическое поведение некоторой сущности, рассматриваемой в определенном контексте. Роль может быть статической или динамической.
Имя роли представляет собой строку текста рядом с концом ассоциации для соответствующего класса. Она указывает на специфическую роль, которую играет класс, являющийся концом рассматриваемой ассоциации. Имя роли не обязательный элемент обозначений и может отсутствовать на диаграмме.
Следующий элемент обозначений – кратность ассоциации. Кратность относится к концам ассоциации и обозначается в виде интервала целых чисел, аналогично кратности атрибутов и операций классов, но без прямых скобок. Этот интервал записывается рядом с концом соответствующей ассоциации и означает потенциальное число отдельных экземпляров класса, которые могут иметь место, когда остальные экземпляры или объекты классов фиксированы.
Так, для примера (рис. 6.87.) кратность "1" для класса Компания означает, что каждый сотрудник может работать только в одной компании. Кратность "1..*" для класса Сотрудник означает, что в каждой компании могут работать несколько сотрудников, общее число которых заранее неизвестно и ничем не ограничено. Вместо кратности "1..*" нельзя записать только символ "*", поскольку последний означает кратность "0..*". Для данного примера это означало бы, что отдельные компании могут совсем не иметь сотрудников в своем штате. Такая кратность приемлема в ситуациях, когда в компании вообще не выполняется никаких проектов.
Имя ассоциации рассматривается в качестве отдельного атрибута у соответствующих классов ассоциаций и может быть указано на диаграмме явным способом в определенной секции прямоугольника класса.
Ассоциация является наиболее общей формой отношения в языке UML. Все другие типы рассматриваемых отношений можно считать частным случаем данного отношения. Однако важность выделения специфических семантических свойств и дополнительных характеристик для других типов отношений обусловливают необходимость их самостоятельного изучения при построении диаграмм классов. Поскольку эти отношения имеют специальные обозначения и относятся к базовым понятиям языка UML, следует перейти к их последовательному рассмотрению.
Отношение обобщения
Отношение обобщения является обычным таксономическим отношением или отношением классификации между более общим элементом (родителем или предком) и более частным или специальным элементом (дочерним или потомком).
Обобщение (Generalization) – таксономическое отношение между более общим понятием и менее общим понятием.
Менее общий элемент модели должен быть согласован с более общим элементом и может содержать дополнительную информацию. Данное отношение используется для представления иерархических взаимосвязей между различными элементами языка UML, такими как пакеты, классы, варианты использования.
Применительно к диаграмме классов данное отношение описывает иерархическое строение классов и наследование их свойств и поведения.
Наследование (Inheritance) – специальный концептуальный механизм, посредством которого более специальные элементы включают в себя структуру и поведение более общих элементов.
Согласно одному из главных принципов методологии ООАП – наследованию, класс–потомок обладает всеми свойствами и поведением класса–предка, а также имеет собственные свойства и поведение, которые могут отсутствовать у класса–предка.
Родитель, предок (Parent) – в отношении обобщения более общий элемент. Потомок (Child) – специализация одного из элементов отношения обобщения, называемого в этом случае родителем.
На диаграммах отношение обобщения обозначается сплошной линией с треугольной стрелкой на одном из концов (рис. 6.88.). Стрелка указывает на более общий класс (класс–предок или суперкласс), а ее начало – на более специальный класс (класс–потомок или подкласс).
Рис. 6.88. Графическое изображение отношения обобщения в языке UML
От одного класса–предка одновременно могут наследовать несколько классов–потомков, что отражает таксономический характер данного отношения. В этом случае на диаграмме классов для подобного отношения обобщения указывается несколько линий со стрелками.
Например, класс Транспортное средство (курсив обозначает абстрактный класс) может выступать в качестве суперкласса для подклассов, соответствующих конкретным транспортным средствам, таким как: Автомобиль, Автобус, Трактор и другим. Это может быть представлено графически в форме диаграммы классов следующего вида (рис. 6.89.).
Рис. 6.89. Пример графического изображения отношения обобщения для нескольких классов–потомков
С целью упрощения обозначений на диаграмме классов и уменьшения числа стрелок–треугольников и совокупности линий, обозначающих одно и то же отношение обобщения, может быть просто изображена стрелка. В этом случае отдельные линии сходятся к стрелке, которая имеет с этими линиями единственную точку пересечения (рис. 6.90.).
Рис. 6.90. Альтернативный вариант графического изображения отношения обобщения классов для случая объединения отдельных линий
Графическое изображение отношения обобщения по форме соответствует графу специального вида, а именно – иерархическому дереву. Как нетрудно заметить, в этом случае класс–предок является корнем дерева, а классы–потомки – его листьями. Отличие заключается в возможности указания на диаграмме классов дополнительной семантической информации, которая может отражать различные теоретико–множественные характеристики данного отношения. При этом класс–предок на диаграмме может занимать произвольное положение относительно своих классов–потомков, определяемое лишь соображениями удобства.
В дополнение к простой стрелке обобщения может быть присоединена строка текста, указывающая на специальные свойства этого отношения в форме ограничения. Этот текст будет относиться ко всем линиям обобщения, которые идут к классам–потомкам. Поскольку отмеченное свойство касается всех подклассов данного отношения, именно поэтому спецификация этого свойства осуществляется в форме ограничения, которое должно быть записано в фигурных скобках.
В качестве ограничений могут быть использованы следующие ключевые слова языка UML:
{complete} – означает, что в данном отношении обобщения специфицированы все классы–потомки, и других классов–потомков у данного класса–предка быть не может.
{incomplete} – означает случай, противоположный первому. А именно, предполагается, что на диаграмме указаны не все классы–потомки. В последующем возможно разработчик восполнит их перечень, не изменяя уже построенную диаграмму.
{disjoint} – означает, что классы–потомки не могут содержать объектов, одновременно являющихся экземплярами двух или более классов.
{overlapping} – случай, противоположный предыдущему. А именно, предполагается, что отдельные экземпляры классов–потомков могут принадлежать одновременно нескольким классам.
С учетом дополнительного использования стандартного ограничения диаграмма классов (рис. 6.90.) может быть уточнена (рис. 6.91.).
Рис. 6.91. Вариант уточненного графического изображения отношения обобщения классов с использованием строки–ограничения
Отношение агрегации
Агрегация (Aggregation) – специальная форма ассоциации, которая служит для представления отношения типа "часть–целое" между агрегатом (целое) и его составной частью.
Отношение агрегации имеет место между несколькими классами в том случае, если один из классов представляет собой сущность, которая включает в себя в качестве составных частей другие сущности. Данное отношение имеет фундаментальное значение для описания структуры сложных систем, поскольку применяется для представления системных взаимосвязей типа "часть–целое". Раскрывая внутреннюю структуру системы, отношение агрегации показывает, из каких элементов состоит система, и как они связаны между собой.
С точки зрения модели отдельные части системы могут выступать в виде, как элементов, так и подсистем, которые, в свою очередь, тоже могут состоять из подсистем или элементов. Таким образом, данное отношение по своей сути описывает декомпозицию или разбиение сложной системы на более простые составные части, которые также могут быть подвергнуты декомпозиции, если в этом возникнет необходимость.
Очевидно, что рассматриваемое в таком аспекте деление системы на составные части представляет собой иерархию, но принципиально отличную от той, которая порождается отношением обобщения. Отличие заключается в том, что части системы никак не обязаны наследовать ее свойства и поведение, поскольку являются самостоятельными сущностями. Более того, части целого обладают собственными атрибутами и операциями, которые существенно отличаются от атрибутов и операций целого.
Графически отношение агрегации изображается сплошной линией, один из концов которой представляет собой не закрашенный внутри ромб. Этот ромб указывает на тот класс, который представляет собой "целое" или класс–контейнер. Остальные классы являются его "частями" (рис. 6.92.).
Рис. 6.92. Графическое изображение отношения агрегации в языке UML
В качестве примера отношения агрегации можно рассмотреть взаимосвязь типа "часть–целое", которая имеет место между классом Системный блок персонального компьютера и его составными частями: Процессор, Материнская плата, Оперативная память, Жесткий диск и Дисковод гибких дисков. Используя обозначения языка UML, компонентный состав системного блока можно представить в виде соответствующей диаграммы классов (рис. 6.93.), которая в данном случае иллюстрирует отношение агрегации.
Рис. 6.93. Диаграмма классов для иллюстрации отношения агрегации на примере системного блока ПК
Отношение композиции
Композиция (Composition) – разновидность отношения агрегации, при которой составные части целого имеют такое же время жизни, что и само целое. Эти части уничтожаются вместе с уничтожением целого.
Отношение композиции – частный случай отношения агрегации. Это отношение служит для спецификации более сильной формы отношения "часть–целое", при которой составляющие части тесно взаимосвязаны с целым. Особенность этой взаимосвязи заключается в том, что части не могут выступать в отрыве от целого, т.е. с уничтожением целого уничтожаются и все его составные части.
Композит (Composite) – класс, который связан отношением композиции с одним или большим числом классов.
Графически отношение композиции изображается сплошной линией, один из концов которой представляет собой закрашенный внутри ромб. Этот ромб указывает на тот класс, который представляет собой класс–композит. Остальные классы являются его "частями" (рис. 6.94.).
Рис. 6.94. Графическое изображение отношения композиции в языке UML
Практический пример этого отношения – окно графического интерфейса программы, которое может состоять из строки заголовка, полос прокрутки, главного меню, рабочей области и строки состояния. Нетрудно заключить, что подобное окно представляет собой класс, а его составные элементы также являются отдельными классами. Последнее обстоятельство характерно для отношения композиции, поскольку отражает различные способы представления данного отношения.
Для отношений композиции и агрегации могут использоваться дополнительные обозначения, применяемые для отношения ассоциации. А именно, могут указываться кратности отдельных классов, которые в общем случае не обязательны. Применительно к описанному выше примеру класс Окно программы является классом–композитом, а взаимосвязи составляющих его частей могут быть изображены следующей диаграммой классов (рис. 6.95).
Рис. 6.95. Диаграмма классов для иллюстрации отношения композиции на примере класса–композита Окно программы
Примеры диаграмм классов
Логическая структура сайта ПЭ НСИ:
Рис. 6.96.
Логическая структура сайта ПЭ НСИ:
Уровень "Отображение" – представляет возможность конечному пользователю работать с БД ПЭ НСИ при помощи удаленного доступа. Отвечает за отображение информации ПЭ НСИ и обработку запросов пользователя. Отображение и ввод данных осуществляется при помощи технологии JSP–Servlete–JSP. На диаграмме представлены страницы JSP (аналог html–страниц, но в отличие от последних обрабатываются не только браузером но и сервером) и схема вызовов каждой из страниц.
Диаграмма логической структуры сайта ПЭ НСИ. Часть 1. Сервер:
Рис. 6.97.
Диаграмма логической структуры сайта ПЭ НСИ. Часть 1. Сервер:
Представлены два сервлета – контроллера, реализующих обработку запросов пользователя. При помощи классов пакета NSISRV_22 сервлеты – контроллеры получают доступ к БД ПЭ НСИ и её виртуальному отображению.
Логическая структура ПО ПЭ НСИ. Часть2. Бизнес логика:
Рис. 6.98.
Диаграмма логической структуры сайта ПЭ НСИ. Часть 2. Бизнес логика:
Представлены классы, реализующие бизнес–логику приложения:
– формирование sql запросов к БД ПЭ НСИ;
– обработка результатов sql запросов;
– виртуализация БД ПЭ НСИ;
– поиск информации;
– изменение информации;
– логирование.
Компоненты
Компонент (Component) – это физическая заменяемая часть системы, совместимая с одним набором интерфейсов и обеспечивающая реализацию какого–либо другого. Компонент изображается в виде прямоугольника с вкладками (рис. 6.99.).
Компоненты используются для моделирования физических сущностей, размещенных в узле: исполняемых модулей, библиотек, таблиц, файлов и документов. Обычно компонент представляет собой физическую пакет логических элементов, таких как классы, интерфейсы и кооперативные диаграммы.
Многие операционные системы и языки программирования непосредственно поддерживают понятие компонента. Объектные библиотеки, исполняемые программы, компоненты Enterprise JavaBeans – все эти примеры сущностей, которые могут быть непосредственно представлены компонентами в смысле UML. Компоненты могут использоваться не только для моделирования такого рода сущностей, но и для представления иных элементов работающей системы – к примеру, таблиц, файлов и документов.
Рис. 6.99. Компонент
Графически компонент в UML изображается так, как показано на рис. 6.102. Это обозначение позволяет рассматривать компонент без привязки к конкретной операционной системе или языку программирования. С помощью стереотипов – одного из механизмов расширения UML – можно приспособить эту нотацию для представления конкретных видов компонентов.
У каждого компонента должно быть имя, отличающее его от других компонентов. Имя – это текстовая строка; взятое само по себе, оно называется простым. В составном имени спереди от простого добавлено имя пакета, в котором находится компонент. Имя компонента должно быть уникальным внутри объемлющего пакета. Обычно при изображении компонента указывают только его имя, как видно из рис. 6.100. Тем не менее, как и в случае с классами, вы можете снабжать компоненты помеченными значениями или дополнительными разделами, чтобы показать детали.
Рис. 6.100. Простое и расширенное изображение компонентов
Имя компонента может состоять из любого числа букв, цифр и некоторых знаков препинания (за исключением таких, как двоеточия, которые применяются для отделения имени компонента от имени объемлющего пакета). Имя может занимать несколько строк. Как правило, для именования компонентов используют одно или несколько коротких существительных, взятых из словаря реализации, и в зависимости от выбранной операционной системы добавляют расширения имен файлов (например, java или dll).
Изображая компонент в UML, руководствуйтесь следующими правилами:
– применяйте свернутую форму интерфейса, если только не возникает острой необходимости раскрыть операции, предлагаемые этим интерфейсом;
– показывайте только те интерфейсы, которые необходимы для понимания назначения компонента в данном контексте;
– в тех случаях, когда вы используете компоненты для моделирования библиотек и исходного кода, указывайте помеченные значения, относящиеся к контролю версий.
Хорошо структурированный компонент обладает следующими свойствами:
предоставляет четкую абстракцию некоторой сущности, которая является частью физического аспекта системы;
предоставляет реализацию небольшого, хорошо определенного набора интерфейсов;
включает набор классов, которые, действуя совместно, реализуют семантику интерфейсов изящно и экономно;
слабо связан с другими компонентами; как правило, компоненты моделируются только совместно, с отношениями зависимости и реализации.
Виды компонентов
Можно выделить три вида компонентов.
Во–первых, это компоненты размещения (Deployment components), которые необходимы и достаточны для построения исполняемой системы. К их числу относятся динамически подключаемые библиотеки (DLL) и исполняемые программы (ЕХЕ). Определение компонентов в UML достаточно широко, чтобы охватить как классические объектные модели, вроде СОМ+, CORBA и Enterprise JavaBeans, так и альтернативные, возможно содержащие динамические Web–страницы, таблицы базы данных и исполняемые модули, где используются закрытые механизмы коммуникации.
Во–вторых, есть компоненты – рабочие продукты (Work product components). По сути дела, это побочный результат процесса разработки. Сюда можно отнести файлы с исходными текстами программ и данными, из которых создаются компоненты размещения. Такие компоненты не принимают непосредственного участия в работе исполняемой системы, но являются рабочими продуктами, из которых исполняемая система создается.
В–третьих, существуют компоненты исполнения (Execution components); Они создаются как результат работы системы. Примером может служить объект СОМ+, экземпляр которого создается из DLL.
Все механизмы расширения UML применимы и к компонентам. Чаще всего используются помеченные значения для расширения свойств компонентов (например, для задания версии компонента) и стереотипы для задания новых видов компонентов (например, зависимых от операционной системы).
В UML определены пять стандартных стереотипов, применимых к компонентам:
executable (исполнимый) – определяет компонент, который может исполняться в узле;
library (библиотека) – определяет статическую или динамическую объектную библиотеку;
table (таблица) – определяет компонент, представляющий таблицу базы данных;
file (файл) – определяет компонент, представляющий документ, который содержит исходный текст или данные;
document (документ) – определяет компонент, представляющий документ.