М. Фаулер, К. Скотт - UML Основы (1114905), страница 22
Текст из файла (страница 22)
Как правило, один и тот же объект в реальном мире может быть представлен целым множеством объектов-значений. Например, вполне нормально, когда имеются сотни объектов со значением «1 января 1999 года». Все эти объекты являются взаимозаменяемыми копиями. При этом новые даты создаются и уничтожаются достаточно часто.
Если у вас имеются две даты и вы хотите установить, являются ли они тождественными, то вполне достаточно просто посмотреть на их значения, а не устанавливать их индивидуальность. Обычно это означает, что в программе необходимо определить оператор проверки равенства, который бы проверял для дат год, месяц и день (каким бы ни было их внутреннее представление). Обычно каждый объект, который ссылается на 1 января 1999 года, имеет свой собственный специальный объект, однако иногда даты могут быть объектами общего пользования.
Объекты-значения должны быть постоянными (неизменяемыми; см. раздел «Постоянство» далее в этой главе). Другими словами, не должно допускаться изменение значения объекта-даты «1 января 1999 года» на «2 января 1999 года». Вместо этого следует создать новый объект «2 января 1999 года» и связать его с первым объектом. Причина запрета подобного изменения заключается в следующем: если бы эта дата была объектом общего пользования, то ее обновление могло повлиять на другие объекты-даты непредсказуемым образом. В прежнее время различие между ссылочными объектами и объектами-значениями было более четким. Объекты-значения являлись встроенными значениями системы типов.
В настоящее время системы типов можно расширять с помощью своих собственных классов, поэтому данный аспект требует более внимательного отношения. В рамках языка ()М1 для объектов-значений обычно используются атрибуты, а для ссылочных объектов — ассоциации.
Для объектов-значений можно также использовать композицию. 105 Постоянство Я не думаю, что различие между ссылочными объектами и объектами- значениями следует учитывать при концептуальном моделировании. Зто может привести к путанице с кратностями. Если я представляю связь с объектом-значением с помощью некоторой ассоциации, то обычно обозначаю кратность на конце такой ассоциации около пользователя данного значения символом «*». Зто происходит лишь в том случае, если для него не существует правила уникальности, такого как использование порядкового номера. Совокупности многозначных концов ассоциаций Многозначный конец ассоциации — это такой конец ассоциации, верхняя граница кратности которого превышает 1 (например, «*»).
Обычно принято рассматривать такие многозначные концы ассоциаций как обычные множества. При этом для соответствующих целевых объектов не существует никакой упорядоченности, и не существует объектов, которые могли бы присутствовать в данном множестве более одного раза. Однако эти правила могут быть изменены с помощью введения дополнительного ограничения. Ограничение (упорядочено) ((огс(еге«1)) устанавливает некоторый порядок на множестве целевых объектов, т.
е. целевые объекты образуют список. В этом списке каждый целевой объект может присутствовать только один раз. Я использую ограничение (комплект) ((Ьаз)), чтобы показать, что целевые объекты на данном конце ассоциации могут появляться более одного раза, но без какой-либо упорядоченности. Я также использую ограничение (иерархия) ((Ь1егагсйу)), чтобы показать наличие некоторой иерархии в множестве целевых объектов, и ограничение (дау) (сокращение от б(гесаб асус11с атарЦ, характеризующее направленный ациклический граф.
ПОСТОЯНСТВО Постоянство (Ггозеп) представляет собой ограничение, которое в языке 1)М1. может быть применено по отношению к атрибуту или концу ассоциации, но, по моему мнению, оно также оказывается полезным применительно к классам. По отношению к атрибуту или концу ассоциации постоянство указывает на то, что значение этого атрибута или конца ассоциации не может быть изменено в течение всего жизненного цикла исходного объекта. Зто значение должно быть задано при создании объекта и после этого уже никогда не может изменяться.
Начальное значение может быть неопределенным (пи11). Разумеется, если данное ограниче- 106 Глава 6.Диаграммы классов: дополнительные понятия ние справедливо при конструировании объекта, оно будет оставаться справедливым в течение всего времени существования объекта. При этом подразумевается, что для данного значения должен присутствовать аргумент в конструкторе и не должно существовать операций, которые могли бы изменить это значение. По отношению к классу постоянство указывает, что все концы ассоциации и атрибуты, связанные с данным классом, являются постоянными. Постоянство и ограничение «только для чтения» (геаг(-оп)у) — это не одно и то же. «Только для чтения» предполагает, что соответствующее значение нельзя изменить непосредственно, однако оно может быть изменено вследствие изменения какого-либо другого значения. Например, если атрибутами личности являются дата рождения и возраст, то возраст может иметь ограничение «только для чтения», но не может быть постоянным.
Я обозначаю постоянство с помощью ограничения (постоянно) ((ггогеп)) и помечаю значения, предназначенные только для чтения, с помощью ограничения (только длл чтения). (При этом следует заметить, что Только Для Чтения не является стандартным элементом языка УМ1 .) Если вы собираетесь определить что-либо как постоянное, следует помнить, что люди способны совершать ошибки. При разработке программного обеспечения человек моделирует только то, что сам знает о реальном мире, не учитывая всей его реальности. Если бы мы моделировали мир таким, какой он есть, то атрибут «дата рождения» для объекта Личность следовало бы определить как постоянный. Однако в большинстве случаев может потребоваться его изменение, если обнаружится, что предыдущая запись была ошибочной. Классификация и обобщение Мне часто приходится слышать разговоры разработчиков о механизме подтипов как об отношении «является». Я настоятельно рекомендую держаться подальше от такого представления.
Проблема заключается в том, что фраза «является» может иметь самый разный смысл. Рассмотрим следующие фразы: 1. Шеп является Пограничным Колли. 2. Пограничный Колли является Собакой. 3. Собаки являются Животными. 4. Пограничный Колли является Породой Собак. б. Собака является Биологическим Видом. Теперь попытаемся скомбинировать эти фразы. Если объединим фразы 1 и 2, то получим «Шеп является Собакой»; фразы 2 и 3 дают в ре- Квалифицированные ассоциации зультате «Пограничные Колли являются Животными». Объединение первых трех фраз дает «Шеп является Животным». Чем дальше, тем лучше.
Теперь попробуем 1 и 4: «Шеп является Породой Собак». Сочетание фраз 2 и б дает «Пограничный Колли является Биологическим Видом». Это уже не так хорошо. Почему некоторые из этих фраз можно комбинировать, а другие нельзя г Потому что некоторые фразы представляют собой классификацию (объект Шеп является экземпляром типа Пограничный Колли), а другие — обобщение (тип Пограничный Колли является подтипом типа Собака). Обобщение транзитивно, а классификация — нет.
Если обобщение следует за классификацией, то в этом направлении их можно комбинировать, а если наоборот, то нельзя. Смысл сказанного заключается в том, что с отношением «является» следует обращаться весьма осторожно. Его использование может привести к неверному применению подклассов н ошибочным результатам. В приведенном примере хорошими тестами для проверки подтипов могут служить следующие фразы: «Собаки являются разновидностью Животных» н «Каждый экземпляр Пограничного Колли является экземпляром Собаки».
Квалифицированные ассоциации Квалифицированная ассоциация в языке ()М) эквивалентна таким известным понятиям в языках программирования, как ассоциативные массивы (аээос1а(1че аггауэ), схемы (шаре) и словари. На рис. 6.13 показан способ представления ассоциации между Заказом и Строкой Заказа, в котором используется квалификатор.
Квалификатор указывает, что в соответствии с Заказом для каждого экземпляра Продукта может существовать одна Строка Заказа. Рис. 6.13. Квалифици)гованнал ассоциация С концептуальной точки зрения этот пример показывает, что отдельный Заказ не может содержать две Строки Заказа для одного и того же Продукта. С точки зрения спецификации данная квалифицированная ассоциация может повлечь создание интерфейса следующего вида: С1ааа Огбег ( риЫ1о Огбогыпа О«тыл«1(ав(Ргобист аРгобист); риЫ1с ио1б аббшпо1С»в(аивоег авоипт, Ргобиот ГогРгобист) 166 Глава б. Диаграччы классов: дополнительные понятия Таким образом, любой доступ к заданной Позиции Заказа требует подстановки некоторого Продукта в качестве аргумента.
Кратность «1» означает, что для каждого Продукта должна существовать только одна Позиции Заказа; кратность «*» означает, что для Продукта может существовать несколько Строк Заказа, однако соответствующий доступ к Позициям Заказа все равно выполняется на основе индексов, образованных с помощью Продукта. С точки зрения реализации для этой цели можно предложить использовать ассоциативный массив или другую аналогичную структуру данных для хранения строк заказа.