Шаг 95.
Унифицированный язык моделирования UML.
Ограничения на связи обобщения в UML

    На этом шаге рассмотрим ограничения на связи обобщения в UML.

    Обобщение – это связь общего классификатора, называемого суперклассом или родителем, и более конкретного, называемого подклассом или дочерним классом. Например, у вас могут быть общий класс Window (Окно) и более конкретный – MultiPanelWindow (МногопанельноеОкно). Если установлена связь обобщения от дочернего к родительскому классу, то первый (MultiPanelWindow) унаследует всю структуру и поведение второго (Window). Притом дочерний класс может в дополнение к этому представить новую структуру и поведение или даже переопределить поведение родителя. В связи обобщения экземпляры потомка могут быть использованы везде, где применимы экземпляры родителя – это означает, что экземпляр потомка может быть подставлен вместо экземпляра родителя.

    В большинстве случаев вам будет достаточно одиночного наследования. О классе, который имеет только одного родителя, говорят, что он использует одиночное наследование. Однако бывают случаи, когда один класс включает в себя аспекты множества других – тогда лучше смоделировать эти связи множественным наследованием. В качестве примера рассмотрим рис. 1, где показан набор классов, составляющих приложение финансовых услуг.


Рис.1. Множественное наследование

    У класса Asset (Активы) три потомка: BankAccount (БанковскийСчет), RealEstate (Недвижимость) и Security (ЦенныеБумаги).

    Два из них – BankAccount и Security – имеют своих собственных потомков. Так, Stock (Акция) и Bond (Облигация) – дочерние классы Security.

    Дочерние классы BankAccount и RealEstate наследуют от множества родителей. Например, RealEstate – это разновидность как Asset, так и InsurableItem (ОбъектСтрахования), а BankAccount – разновидность Asset, InterestBearingItem (ОбъектНачисленияПроцентов), и InsurableItem.

    Некоторые суперклассы используются только для того, чтобы добавить, как правило, поведение и иногда – структуру к классам, которые наследуют свою основную структуру от обычных суперклассов. Эти дополнительные классы называются примесями (mixins); они не могут применяться автономно, всегда выступая в качестве добавочных суперклассов в связи множественного наследования. Например, InterestBearingItem и InsurableItem на рис. 1 – примеси.

    Применяйте множественное наследование осторожно: вы можете столкнуться с проблемами, если дочерний класс имеет нескольких родителей, структура и поведение которых перекрываются. Во многих случаях множественное наследование может быть заменено делегацией, когда дочерний класс наследует только от одного родителя, а затем посредством агрегации перенимает структуру и поведение второстепенных родителей. Например, вместо специализации класса Vehicle (Транспорт), с одной стороны, по принципу LandVehicle (НаземныйТранспорт), WaterVehicle (ВодныйТранспорт) и AirVehicle (ВоздушныйТранспорт), а с другой, по принципу GasPowered (НаГазовойЭнергии), WindPowered (НаВетровойЭнергии) и MusclePowered (НаМускульнойЭнергии), допустите, чтобы класс Vehicle содержал в виде составной части meansOfPropulsion (движущаяСила). Главный недостаток данного подхода в том, что для таких второстепенных родителей утрачивается семантика подстановки.

    Простой, без дополнений, связи обобщения будет достаточно в большинстве случаев наследования, с которыми вы столкнетесь. Однако если вы хотите подчеркнуть тонкие смысловые оттенки, на помощь приходят существующие в UML ограничения, которые могут быть наложены на связи обобщения:

  1. complete – показывает, что все дочерние классы в обобщении специфицированы в модели (хотя некоторые могут быть не указаны на диаграмме) и никакие дополнительные дочерние классы не допускаются;
  2. incomplete – показывает, что не все дочерние классы в обобщении специфицированы в модели (даже если некоторые и пропущены) и допускается создание дополнительных дочерних классов.

        Если только не указано иное, вы можете предполагать, что любая диаграмма показывает только частичное представление структуры наследования – остальная часть пропущена. Однако это не имеет отношения к завершенности модели. В частности, ограничение complete следует использовать, когда вы хотите явно показать, что иерархия наследования в модели показана полностью (хотя вполне возможно, что ни одна диаграмма не отражает всю иерархию целиком). Ограничение incomplete позволяет явно указать, что вы не устанавливаете полную иерархию в модели (хотя одна диаграмма может показать все, что в этой модели есть).

  3. disjoint – означает, что объект родительского класса может принадлежать только одному типу классов-потомков. Например, класс Person (Человек) может быть специализирован путем создания disjoint-классов Man (Мужчина) и Woman (Женщина).
  4. overlapping – означает, что объект родительского класса может принадлежать нескольким типам классов-потомков. И подклассы именно перекрывающиеся. Например, класс Vehicle (Транспорт) может быть специализирован путем создания подклассов LandVehicle (НаземныйТранспорт) и WaterVehicle (ВодныйТранспорт); автомобиль-амфибия относится к обоим.

        Последние два ограничения относятся только к ситуациям множественного наследования. Используйте disjoint, чтобы показать, что классы в наборе являются взаимно несовместимыми; подкласс не может наследовать от нескольких родителей. Применяйте overlapping, если нужно показать, что класс допускает множественное наследование от более чем одного класса в наборе.

    В большинстве случаев во время исполнения объект имеет один тип – тогда мы имеем дело со статической классификацией. Если же объект может изменять свой тип во время исполнения, это пример динамической классификации. Моделировать последнюю сложно, но в UML вы можете вместо динамической классификации использовать сочетание множественного наследования (чтобы показать возможные типы объекта), типов и взаимодействий (чтобы показать изменение типа объекта во время исполнения).

    На следующем шаге рассмотрим базовые дополнения к ассоциациям в UML.




Предыдущий шаг Содержание Следующий шаг