Общая проблема диаграмм последовательности заключается в том, как отображать циклы и условные конструкции. Прежде всего надо усвоить, что диаграммы последовательности для этого не предназначены. Подобные управляющие структуры лучше показывать с помощью диаграммы деятельности или собственно кода. Диаграммы последовательности применяются для визуализации процесса взаимодействия объектов, а не как средство моделирования алгоритма управления.
Как было сказано, существуют дополнительные обозначения. И для циклов, и для условий используются фреймы взаимодействий (interaction frames), представляющие собой средство разметки диаграммы взаимодействия. На рис. 4.4 показан простой алгоритм, основанный на следующем псевдокоде.
foreach (lineitem)
if (product.value > $10K)
careful.dispatch
else
regular.dispatch
end if
end for
if (needsConfirmation) messenger.confirm end procedure
В основном фреймы состоят из некоторой области диаграммы последовательности, разделенной на несколько фрагментов. Каждый фрейм имеет оператор, а каждый фрагмент может иметь защиту. (В табл. 4.1 перечислены общепринятые операторы для фреймов взаимодействия.) Для отображения цикла применяется оператор loop с единственным фрагментом, а тело итерации помещается в защиту. Для условной логики можно использовать оператор alt и помещать условие в каждый фрагмент. Будет выполнен только тот фрагмент, защита которого имеет истинное значение. Для единственной области существует оператор opt
Фреймы взаимодействия - новинка UML2. В диаграммах, разработанных до создания UML, 2, применяется другой подход; кроме того, некоторые разработчики не любят фреймы и предпочитают прежние соглашения. На рис. 4.5 показаны некоторые из этих неофициальных приемов.
В UML 1 использовались маркеры итераций и защиты. В качестве маркера итерации (iteration marker) выступал символ *, добавленный к имени сообщения. Для обозначения тела итерации можно добавить текст в квадратных скобках. Защита (guard) - это условное выраже-
ние, размещенное в квадратных скобках и означающее, что сообщение посылается, только когда защита принимает истинное значение. Эти обозначения исключены из UML 2, но они все еще встречаются в диаграммах взаимодействия.
Несмотря на то что маркеры итерации и защиты могут оказаться полезными, они имеют один недостаток. С помощью защиты нельзя показать, что несколько защит взаимно исключают друг друга, например две защиты, представленные на рис. 4.5. Оба обозначения работают только в случае отправки одного сообщения и не работают, когда при одной активации посылается несколько сообщений в рамках того же самого цикла или условного блока.
Решением последней проблемы может служить ставшее популярным неофициальное соглашение, заключающееся в применении псевдосообщения (pseudomessage) в виде условия цикла или защиты на одном из вариантов обозначения самовызова. На рис. 4.5 я показал это без стрелки сообщения; некоторые разработчики включают стрелку сообщения, но ее отсутствие помогает подчеркнуть, что это ненастоящий вызов. Некоторые разработчики любят оттенять прямоугольник активации псевдосообщения серым цветом. Вариативное поведение можно показать, поставив маркер альтернативы между активациями.
Хотя я считаю активации очень полезными, они не слишком много дают в случае метода dispatch (перенаправить), с помощью которого отправляются сообщения, при этом в рамках активации приемника больше ничего не происходит. По общепринятому соглашению, которого я придерживался в диаграмме на рис. 4.5, для таких простых вызовов активация опускается.
Стандарт UML не предоставляет графических средств для обозначения передаваемых данных; вместо этого они показываются с помощью параметров в имени сообщения и на стрелках возврата. Векторы данных
повсеместно использовались во многих областях для обозначения перемещения данных, и многие разработчики все еще с удовольствием применяют их в UML.
В конечном счете, хотя различные системы могут включать в диаграммы последовательности обозначения для условной логики, я не думаю, что они работают сколько-нибудь лучше программного кода или, по крайней мере, псевдокода. В частности, я считаю фреймы взаимодействия очень тяжеловесными, скрывающими основной смысл диаграммы, поэтому я предпочитаю псевдосообщения.