Шаг 51.
Унифицированный язык моделирования UML.
Типичные приемы моделирования классов в UML

    На этом шаге рассмотрим приемы моделирования классов в UML.

    Моделирование словаря системы

    Чаще всего классы используются для моделирования абстракций, происходящих от проблем, которые нужно решить, либо от технологий, используемых для решений этих проблем. Каждая из таких абстракций является частью словаря системы, то есть вместе взятые, они представляют совокупность понятий, важных для пользователей и разработчиков.

    Для пользователей идентифицировать большинство абстракций не так сложно, потому что последние, как правило, происходят от тех элементов и понятий, которые уже используются для описания систем. Методика применения CRC-карт и анализа на основе вариантов использования – отличный способ помочь найти эти абстракции. Что же касается разработчиков, для них подобные абстракции обычно являются всего лишь технологическими сущностями, представляющими части решения.

    Чтобы смоделировать словарь системы, необходимо:

  1. Идентифицировать те сущности, которыми оперируют пользователи или разработчики для описания проблемы или ее решения. Использовать CRC-карты и анализ на основе вариантов использования для выявления этих абстракций.
  2. Для каждой абстракции идентифицировать набор ее обязанностей. Убедиться, что каждый класс четко определен и обязанности сбалансировано распределены между классами.
  3. Представить атрибуты и операции, необходимые для выполнения обязанностей каждого класса.

    Рис. 1 показывает набор классов, предназначенный для реализации системы розничной торговли и содержащий классы Customer (Покупатель), Order (Заказ) и Product (Продукт). Также рисунок включает несколько других абстракций, связанных с основными, они взяты из словаря проблемной области. Это Shipment (Поставка) используется для отслеживания заказов; Invoice (Счет-фактура) для оплаты заказов; Warehouse (Склад) – место хранения товаров перед отправкой. Есть также одна абстракция, имеющая отношение к решению: Transaction (Транзакция). Она применяется к заказам и поставкам.


Рис.1. Пример моделирования словаря системы в UML

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

    Редко когда ваши модели будут абсолютно статическими. Скорее всего, абстракции из словаря вашей системы в большинстве своем будут динамически взаимодействовать друг с другом. UML предусматривает множество способов моделирования динамического поведения.

    Моделирование распределения обязанностей в системе

    Если вам придется моделировать немало классов, вы захотите убедиться, что ваши абстракции обеспечивают сбалансированный набор обязанностей. Иными словами, нельзя допустить, чтобы какой-то из классов оказался слишком большим или слишком маленьким.

    Каждый класс должен хорошо выполнять одну задачу. Если вы абстрагируете классы, которые окажутся слишком большими, то обнаружите, что ваша модель трудно поддается изменениям и не слишком удобна для повторного использования. Если же абстрагировать слишком маленькие классы, у вас будет слишком много абстракций, которые трудно понять и которыми трудно управлять. UML поможет визуализировать и специфицировать баланс обязанностей.

    Чтобы смоделировать распределение обязанностей в системе, необходимо:

  1. Идентифицировать множество классов, работающих совместно для достижения некоторого поведения.
  2. Идентифицировать набор обязанностей каждого из этих классов.
  3. Рассмотреть множество классов как одно целое; расчленить классы, на которые приходится слишком большая доля обязанностей, на меньшие абстракции; объединить мелкие классы с тривиальными обязанностями в более крупные; перераспределить обязанности так, чтобы для каждой абстракции был отведен их оптимальный набор.
  4. Рассмотреть способы взаимодействия классов и перераспределить их обязанности исходя из того, что ни один класс не должен делать слишком мало или слишком много.

    В качестве примера на рис. 2 приведен набор классов, взятый из языка Smalltalk, показывающий распределение обязанностей между классами Model (Модель), View (Представление) и Controller (Контроллер). Все эти классы работают вместе так, что ни одному из них не приходится делать слишком много или мало.


Рис.2. Пример моделирования распределения обязанностей в системе

    Моделирование непрограммных сущностей

    Иногда сущности, которые вы моделируете, не имеют аналога в программном обеспечении. Например, люди, которые посылают счета, и роботы, которые автоматически пакуют заказы для поставок со складов, могут быть частью потока работ, моделируемого для торговой системы. Ваше приложение может не иметь никаких программных компонентов, которые представляют сущности (в отличие от заказчиков в приведенном примере, поскольку ваша система, вероятно, будет поддерживать информацию о них).

    Чтобы моделировать непрограммные сущности, необходимо:

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

    Как показано на рис. 3, вполне допустимо абстрагировать людей (в данном примере – AccountsReceivableAgent, (АгентПоДебиторскойЗадолженности) и аппаратное обеспечение Robot (Робот) в виде классов, потому что они представляют собой множества объектов с общей структурой и общим поведением.


Рис.3. Пример моделирования непрграммных сущностей в UML

    Моделирование примитивных типов

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

    Чтобы моделировать примитивные типы, необходимо:

  1. Смоделировать абстрагируемую сущность в виде класса или перечисления, изображая ее в нотации класса с соответствующим стереотипом.
  2. Если вам нужно специфицировать диапазон значений, ассоциированный с этим типом, используйте ограничения.

    По рис. 4 видно, что эти сущности могут быть смоделированы на UML как типы или перечисления, которые изображаются как классы, но с явно отмеченными стереотипами. Примитивные типы, такие как целые числа (представленные классом Int), моделируются как типы, и вы можете явно указать диапазоны их допустимых значений, используя ограничения; семантика примитивных типов должна быть определена вне UML. Перечислимые типы, Boolean (Булев) и Status (Состояние) могут быть смоделированы перечислениями со своими собственными индивидуальными литералами, указанными в разделе атрибутов (отметим, однако, что атрибутами они не являются). Перечислимые типы также могут определять операции.


Рис.4. Пример моделирования примитивных типов в UML

    Моделируя классы на UML, помните, что каждый класс должен отображать некоторую осязаемую или концептуальную абстракцию из предметной области конечного пользователя или разработчика.

    Хорошо структурированный класс обладает следующими признаками:

    Изображая класс в UML, вы должны:

  1. показать только те его свойства, которые важны для понимания абстракции в данном контексте;
  2. организовать длинные списки атрибутов и операций, группируя их по категориям;
  3. представить взаимосвязанные классы на одной диаграмме.

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




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