Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

АрхитектураИС_Семестр3_МетодПособие8-9

.pdf
Скачиваний:
18
Добавлен:
05.06.2015
Размер:
603.53 Кб
Скачать

31

Customer

 

Business Rules::FraudAgent

 

 

 

 

простые имена

составные имена

 

 

 

 

 

 

Temperature Sensor

 

 

 

 

 

 

 

 

 

java::awt::Rectsngle

 

 

 

 

 

 

 

Wall

 

 

 

 

 

 

 

 

 

Рис. 2.2. Простые и составные имена

Имя класса может состоять из любого числа букв, цифр и ряда знаков препинания (за исключением таких, например, как двоеточие, которое применяется для отделения имени класса от имени объемлющего пакета). Имя может занимать несколько строк. На практике для именования класса используют одно или несколько коротких существительных, взятых из словаря моделируемой системы. Обычно каждое слово в имени класса пишется с заглавной буквы, например: Customer (Клиент), Wall (Стена), TemperatureSensor (ДатчикТемпера-

туры).

Атрибуты.

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

 

 

мер, у любой стены есть высота, ширина

 

атрибуты

и толщина; при моделировании клиен-

Customer

тов можно задавать фамилию, адрес,

Name

 

Adress

 

номер телефона и дату рождения. Таким

Phone

 

образом, атрибут является абстракцией

BirhDate

 

 

данных объекта или его состояния. В

 

 

 

 

Рис. 2.3. Атрибуты

каждый момент времени любой атрибут

объекта, принадлежащего данному клас-

 

 

су, обладает вполне определенным значением. Атрибуты представлены в разделе, который расположен под именем класса; при этом указываются только их имена (см. рис. 2.3).

Имя атрибута, как и имя класса, может быть произвольной текстовой строкой. На практике для именования атрибута используют одно или несколько коротких существительных, соответствующих некоторому

32

свойству объемлющего класса. Каждое слово в имени атрибута, кроме самого первого, обычно пишется с заглавной буквы, например name или loadBearing.

Wall

атрибуты

height : Float width : Float thickness : Float

isLoadBearing : Boolean

Рис. 2.4. Атрибуты и их классы

При

описании

атрибута

можно

явным

образом

указывать его класс и на-

чальное

значение, прини-

маемое по умолчанию, как

продемонстрировано

на

рис. 2.4.

 

 

Операции

Операцией называется реализация услуги, которую можно запросить у любого объекта класса для воздействия на поведение. Иными словами, операция - это абстракция того, что позволено делать с объектом. У всех объектов класса имеется общий набор операций. Класс может содержать любое число операций или не содержать их вовсе. Например, для всех объектов классаRectangle (Прямоугольник) из библиотеки для работы с окнами, содержащейся в пакете awt языка Java,определены операции перемещения, изменения размера и опроса значений свойств. Часто (хотя не всегда) обращение к операции объекта изменяет его состояние или его данные. Операции класса изображаются в разделе, расположенном ниже раздела с атрибутами. При этом можно ограничиться только именами, как показано на рис. 2.5. Более детальная спецификация выполнения операции осуществ-

 

 

ляется с помощью примечаний и диа-

 

 

грамм деятельности.

 

 

Rectangle

операции

 

Имя операции, как и имя класса,

add()

может

быть

произвольной

текстовой

 

строкой.

На практике

для именования

grow()

 

move()

 

операций используют

короткий глагол

isEmpty()

 

 

или

глагольный

оборот, соответст-

 

 

Рис. 2.5. Операции

вующий

определенному

поведению

 

 

объемлющего

класса.

Каждое

слово в

имени операции, кроме самого первого, обычно пишут с заглавной буквы, например move или isEmpty.

Операцию можно описать более подробно, указав ее сигнатуру, в которую входят имена и типы всех параметров, их значения, принятые по умолчанию, а применительно к функциям - тип возвращаемого значения, как показано на рис. 2.6.

33

TemperatureSensor операции

reset()

setAlarm(t : Temperature) value() : Temperature

Рис. 2.6. Операции и их сигнатуры

Организация атрибутов и операций

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

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

Менеджер доступа

<<constructor>> new()

стереотип <<constructor>> new(p : Policy) <<process>> Обслужить(z:Zapros)

<<query>> IsActive(z : Zapros) <<helper>> ValidateZapros(z : Zapros)

Рис. 2.7. Использование стереотипов для описания свойств класса

Обязанности

Обязанности (Responsibilities) класса - это своего рода контракт, которому он должен подчиняться. Определяя класс, вы постулируете, что все его объекты имеет однотипное состояние и ведут себя одина-

34

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

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

Графически обязанности изображают в особом разделе в нижней части пиктограммы класса (см. рис. 2.8).

Менеджер доступа

Обязанности

определить права пользователя на доступ к данным

обработать зависящий от пользователя запрос

Рис. 2.8. Обязанности

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

Другие свойства

35

При создании абстракций вам чаще всего придется иметь дело с атрибутами, операциями и обязанностями. Для большинства моделей этого вполне достаточно, чтобы описать важнейшие черты семантики классов. Но иногда приходится визуализировать или специфицировать и другие особенности, как то: видимость отдельных атрибутов и операций, специфические для конкретного языка программирования свойства операции(например, является ли она полиморфной или константной) или даже исключения, которые объекты класса могут возбуждать или обрабатывать. Эти и многие другие особенности тоже можно выразить в UML, но в таком случае требуется обращение к более развитым возможностям языка.

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

Переходя к разработке более сложных моделей, вы всякий раз будете сталкиваться с теми же классами(которые представляют, например, параллельные процессы и потоки или физические сущности, в частности апплеты, компоненты JavaBeans и СОМ+, файлы, Webстраницы, аппаратные средства). Поскольку подобные классы очень распространены и представляют важные архитектурные абстракции, в UML имеются такие элементы, как активные классы, компоненты и узлы.

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

2.2. Типичные приемы моделирования. Словарь системы

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

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

36

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

Моделирование словаря системы включает в себя следующие этапы:

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

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

3. Разработайте атрибуты и операции, необходимые для выполнения классами своих обязанностей.

Warehouse

customer

 

 

имя

 

 

адрес

 

Order

телефон

 

 

 

товар

датаРождения

 

 

количество

 

 

 

 

 

 

 

 

 

 

 

Invoice

Transaction

action

Commit()

RollBack()

wasSuccessful()

Product

идентификатор

название

цена

местонахождение

Shipment

Обязанности

сохранять информацию о товарах, поставленных по закзам

отслеживать состояние и местонахождение товаров

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

На рис. 2.9 показан набор классов для системы розничной торговли: Customer (Клиент), Order (Заказ) и Product (Товар). Представлено несколько соотнесенных с ними абстракций, взятых из словаря

37

проблемной области: Shipment (Отгрузка), Invoice (Накладная) и Warehouse (Склад). Одна абстракция, а именно Transaction (Транзакция), применяемая к заказам и отгрузкам, связана с технологией решения задачи.

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

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

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

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

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

всебя следующие этапы:

1.Идентифицируйте совокупность классов, совместно отвечающих за некоторое поведение.

2.Определите обязанности каждого класса.

3.Взгляните на полученные классы как на единое целое и разбейте те из них, у которых слишком много обязанностей, на меньшие - и наоборот, крошечные классы с элементарными обязанностями объедините в более крупные.

4.Перераспределите обязанности так, чтобы каждая абстракция стала в разумной степени автономной.

5.Рассмотрите, как классы кооперируются друг с другом, и перераспределите обязанности с таким расчетом, чтобы ни один класс в рамках кооперации не делал слишком много или слишком мало.

Вкачестве примера на рис. 2.10 показано распределение обязан-

38

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

2.3. Непрограммные сущности

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

Model

Обязанности

управлять состоянием модели

Controller

Обязанности

синхронизировать изменение модели и ее видов

View

Обязанности

изображать модель на экране

управлять перемещением и изменением размера поля зрения

перехватывать события пользователя

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

Моделирование непрограммных сущностей производится -сле дующим образом:

1.Смоделируйте сущности, абстрагируемые в виде классов.

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

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

39

Примечание UML предназначен в первую очередь для моделирования программных систем, однако в сочетании с текстовым языком моделирования аппаратных средств, таким как VHDL, его вполне допустимо использовать и для моделирования аппаратных систем.

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

 

 

Robot

 

 

 

Account Receivable Agent

 

processOrder()

 

 

 

 

changeOrder()

 

 

 

status()

 

 

 

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

2.4. Примитивные типы

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

Моделирование примитивных типов производится следующим образом:

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

2.Если требуется задать связанный с типом диапазон значений, воспользуйтесь ограничениями.

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

40

ные значения становятся атрибутами.

Примечание Такие языки, как Си C++, позволяют определить эквивалентные целые значения для перечислений. Подобное моделирование возможно и в UML, если указать для атрибута, обозначающего перечисление, константное начальное значение по умолчанию.

<<type>>

int {диапазон значений от

-2**31-1 до 2**31}

<<enumiration>>

 

 

 

<<enumiration>>

Status

 

Boolean

idle

 

false

working

 

true

eror

 

 

 

 

 

 

 

 

 

 

Рис. 4.12. Моделирование примитивных типов

2.5. Рекомендации к моделированию классов

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

-является четко очерченной абстракцией некоторого понятия из словаря проблемной области или области решения;

-содержит небольшой, точно определенный набор обязанностей

ивыполняет каждую из них;

-поддерживает четкое разделение спецификаций абстракции и ее реализации;

-понятен и прост, но в то же время допускает расширение и адаптацию к новым задачам.

Изображая класс в UML, придерживайтесь следующих правил:

-показывайте только те его свойства, которые важны для понимания абстракции в данном контексте;

-разделяйте длинные списки атрибутов и операций на группы в соответствии с их категориями;

-показывайте взаимосвязанные классы на одной и той же диаграмме.