GrandM-Patterns_in_Java
.pdfГлава 2. Обзор UML • 35
ЭТОони означает, что если несколько потоков вызывают метод одновременно, то все выполняют его параллельно и правильно.
(concu rrency = gua rded)
Это значит, что если несколько потоков вызывают метод одновременно, то
в какой-то момент времени только одному потоку будет разрешено выполнять
метод. Пока один поток выполняет метод, другие потоки вынуждены ждать
своей очереди. Это похоже на поведение синхронизированных методов в Java.
Диаграмма взаимодействия, представленная на рис. 2.27, демонстрирует при
мер синхронизированного метода.
|
:EMailEncrypter |
||
1 1:lo,Messa"Rec';pt(p ;"T,""M;m,Мs,) {<o","","<y-,uanld) |
|
|
|
..-----'--- |
|||
|
,;J.Qgш |
|
|
Рис. 2.27. Вызов синхронизированного метода |
|
|
Сушествуют определенные тонкости при синхронизации потоков, рассмотрен ные в данной книге и не имеющие стандартного представления в UML. Для описания этих тонкостей в конструкции {concur rency = guarded} использу ются дополнительные пояснения.
В некоторых случаях объект, потоки которого должны быть синхронизированы,
отличается от объекта, метод которого вызывается взаимодействием с этимJ.1
потоками. Рассмотрим рис. 2.28. Представленное на этой диаграмме выражени{
{concurrency = guarded : lockObj ect} ссылается на объект lockObj ect,
Перед реальным обращением к методу поток, контролирующий вызов, должен заблокировать объект out. В семантике Java это соответствует синхронизиро
ванному оператору.
1 |
|
|
I |
:EMailEncrypter |
I |
|
|
|
||||
1: |
lо,Мessa"Rш;рt(р ;"Т"":М'm,М,,) {concurren cy-guarded:out} |
|
|
|
|
|
||||||
|
|
|
1.2:getSessionInfo() |
|||||||||
|
|
|
|
|
|
|
|
|
||||
|
11.1: |
I |
|
|
I |
|||||||
|
|
|
|
|
||||||||
|
|
|
pгint(:Date) |
|
|
|
|
|
|
|
|
|
|
|
1.3: pгint(message:Stгing) |
|
|
|
|
|
|
||||
|
|
|
l |
|
|
I |
|
|
|
|||
|
|
|
|
|
I |
|||||||
|
|
|
out:PгintStream |
|||||||||
|
|
|
|
Рис. 2.28. Синхронизация, использующая третий объект
36 • Глава 2. Обзор UML
Иногда кроме блокировки необходимы некоторые другие предварительные ус
ловия, которые должны удовлетворяться до того, как поток сможет осущест
вить вызов метода. В данной книге перед такими условиями стоит вертикаль
ная черта. На диаграмме взаимодействия, представленной на рис. 2.29, указаны
предварительные условия (им предшествует слово guarded и вертикальная
черта).
lА: addPrintJob(:PrintJob) {сопсurrепсу-guаrdеdLI!рq.isFull()}
pg:PrintQueue
:PrintDriver
Рис. 2.29. Очередь заданий вывада на печать
Эта диаграмма взаимодействия описывает два асинхронных взаимодействия. Одно вызывает метод addPrintJob объекта PrintQueue с целью добавления задания по выводу на печать в объект Pr intQueue. В ходе других взаимодейст вий объект PrintDriver вызывает метод getPrintJob объекта PrintQueue
для извлечения задания по выводу на печать из объекта PrintQueue. Оба взаи модействия имеют предварительные условия синхронизации. Если очередь принтера заполнена, то вызывающее метод addPrintJob взаимодействие ожи дает свободного места в очереди, перед тем как вызвать метод addPrintJob. Если очередь принтера пуста, то перед тем, как вызвать метод getPrintJob, вызывающее этот метод взаимодействие ОЖИдает, пока в очереди не появится задание.
Существуют такие предварительные условия, которые, как правило, задаются
не с помощью выражения, а требуют, чтобы некоторое взаимодействие не на
чиналось до тех пор, пока не закончатся два или более других взаимодействий.
Неявное предварительное условие для всех взаимодействий состоит в том, что
они не начинаются до тех пор, пока не закончится взаимодействие, непосред ственно им предшествующее. Например, взаимодействие с номером 1 .2.4 не
начнется до тех пор, пока не завершится взаимодействие 1 .2.3.
Перед тем как начаться, некоторые взаимодействия должны ожидать заверше
ния дополнительных, или предварительных, взаимодействий. Такие дополни
тельные (предварительные) взаимодействия представлены в виде списка, ука
занного слева от взаимодействия; затем идет наклонная черта (1) и остальная
часть описания взаимодействия. На диаграмме взаимодействия, изображенной
на рис. 2.30, показан пример предварительных взаимодействий.
Согласно рис. 2.30, взаимодействие 2. la. l не должно начинаться до тех пор, пока не закончится взаимодействие 1 . 1 .2. Если перед тем, как начаться, взаи-
Глава 2. Обзор UML • 37
модействие должно ожидать окончания не одного, а нескольких дополнитель
ных предварительных взаимодействий, они указываются перед наклонной чер
той и отделяются друг от друга запятыми.
|
|
|
|
lCompositeTransactionLogic |
|
|
|
|
|
|
|
|
1.1: register(wrap1) |
1.2а: startTransactionO |
|
||||||||
|
2 . 1: commit() |
|
|
|
|
|
|
||||
|
|
|
|
|
1 .1.1: synchronizeO |
|
|
|
|
|
|
|
|
|
|
|
1.1.2: status1:=getStatusO |
|
|
|
|
|
|
|
|
|
1 . 1 .2f[аll stаtus=..SUССЕSS] 2.1а.1:соmmЩ) |
|
|||||||
|
|
|
|
|
[апу status-FАILURЕ] 2.1а.2:аЬоrtО |
|
|
|
|||
Coordinator |
|
|
|
|
wrap1:xWrapper |
||||||
|
|
|
|
|
|
|
|||||
|
|
|
|
|
|
|
Рис. 2.30. Дополнительные (предварительные) взаимодействия
Механизмы, рассматривавшиеся до настоящего момента, определяют, когда вызываются методы взаимодействия. Однако они ничего не сообщают о том, когда методы завершают свою работу. Стрелки, которые указывают на объекты, содержащие вызываемые методы, информируют о том, когда эти методы могут закончить свою работу.
Почти все стрелки, изображенные на рис. 2.30, заканчиваются замкнутым конту ром, что свидетельствует о синхронности этих вызовов. Выполнение метода не осуществляетсядо тех пор, пока метод не сделает всето, что он должен сделать.
Незамкнутые контуры стрелок указывают на асинхронный вызов метода, кото рый выполняется сразу. Метод в это время работает асинхронно, в отдельном
потоке. Изображенная на рис. 2.31 диаграмма взаимодействия демонстрирует
асинхронный вызов метода.
)
1: write(:String)
:IOManager
Рис. 2.31. Асинхронный вызов метода
UML определяет вид стрелок только для синхронных и асинхронных обраще
ний. для указания других различных обращений к методам допускается приме
нение расширения UML, которое предусматривает использование стрелок дру
гих видов. Отменяемый вызов в этой книге обозначается стрелкой, изогнутой
в обратном направлении (рис. 2.32).
1 : flushO :ТоilеtСопtrQLLеr
Рис. 2.32. Отменяемый вызов
38 • Глава 2. Обзор UML
Если при отменяемом вызове метода объекта никакие другие потоки не выпол
няют методы этого объекта, то он заканчивается, выполнив свою работу. Однако
если при отменяемом вызове метода существует другой поток, выполняющий
в данный момент этот метод объекта, то он завершается сразу, не выполнив ни каких действий.
Вы могли заметить, что объект, который осуществляет вызов высшего уровня,
инициируюший сотрудничество, не показан ни на одной диаграмме взаимо действия. Если объект, инициируюший сотрудничество, не указан на диаграмме
взаимодействия, то этот объект не считается частью взаимодействия.
До этого мы рассматривали описываемые с помошью UML объекты, пассив ные по своей природе. Они ничего не делают до тех пор, пока не вызывается
один из методов этих объектов.
Некоторые объекты являются активными. Они связаны с потоком, позволяющим им инициировать операции асинхронно и независимо от любых действий про
граммы. Активный объект изображается в виде прямоугольника с более жир ным контуром (рис. 2.33).
|
s:Sensor |
||
1 " |
|
|
|
,,"fy(s) |
1 |
|
|
1 |
|
||
|
|
||
:SensorQbserver |
|||
Рис. 2.33. |
Активный объект Sensor |
На диаграмме показан активный объект Sелsоr, вызываюший метод объекта SелsоrОЬsеrvеr, и этому не предшествует обрашение другого объекта к одно
му из методов этого объекта.
Диаграмма состояний
Диаграммы состояний (рис. 2.34) предназначены для моделирования поведения
класса как конечного автомата.
На диаграмме состояний каждое состояние изображено в виде прямоутольника с закругленными углами. Все состояния, показанные на рис. 2.34, разделены на
две части. Верхняя часть содержит имя состояния, нижняя - список событий,
на которые реагирует объект, находясь в данном состоянии и не изменяя это
состояние. За каждым событием списка следует наклонная черта и описание действия, выполняемого в ответ на событие. UML предопределяет два события
такого рода: |
|
• |
событие елtеr происходит тогда, когда объект входит в состояние; |
• |
событие exi t происходит тогда, когда объект выходит из состояния. |
|
|
|
|
|
|
|
Глава |
2. |
|
Обзор UML • 39 |
||||
- |
... |
|
|
|
|
Не изменен |
|
|
|
" |
|
|
|
|
|
"1 nter / Запрещены кнопки Save, Apply иRevert диалогового окна |
|
|
|
||||||||||
|
|
|
||||||||||||
|
|
|
|
|
|
|
|
|
|
|
Кнопка Save / |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
||
|
|
|
|
|
|
r |
Файл изменен |
saveParam() |
|
|
||||
|
|
|
Изменяет |
|
|
|
|
|||||||
|
|
|
|
РазрешеныЗапрещенакнопки |
кнопкаи |
Applyдиалогового окна; |
J |
|||||||
|
|
|
- |
|
||||||||||
|
|
|
|
|
|
Enter / |
Save |
Revert |
|
|||||
|
|
|
|
|
|
|
Не обновленный |
|
applyParam()Кнопка |
|
||||
|
|
|
|
|
|
|
|
|
||||||
|
|
|
|
|
|
|
|
|
|
|
Apply / |
|
||
|
|
|
|
(' |
|
ИзменеН"1 и файл, и объект |
|
|
" |
|
|
|
||
|
|
|
|
|
|
|
|
|
|
|||||
|
Изменяет |
(5'I Разр.w,"ы '"о'"' Apply, 5"" , ,...п ''''0"''0"' ".. .J |
|
|
Рис. 2.34. Диаграмма состояний
Если все события заставляют объект изменять свое состояние, прямоугольни!< состояния не разделяется на две части. При этом прямоугольник с закруглен ными углами содержит только имя состояния.
Каждый конечный автомат имеет начальное состояние, в котором находитс}; объект перед первым переходом в другое состояние. Исходное состояние изо бражается в виде маленького закрашенного кружка.
На диаграмме состояний переходы между состояниями показаны в виде линий
Обычно линия перехода должна иметь метку, обозначающую событие, которо( инициирует переход. За событием может следовать наклонная черта и описа· ние действия, выполняемого во время перехода.
Если диаграмма содержит конечное состояние, то оно изображается в виде ма·
ленького закрашенного кружка, находяшегося внутри более крупного кружка
Диаграмма развертывания ю
диаграмма развертывания показывает, каким образом ПО развертывается
вычислительные элементы. На рис. 2.35 представлен пример диаграммы раз
вертывания.
На рис. 2.35 изображены два вычислительных элемента, помеченных каl
S e rve r l и S e rve r2 . Согласно терминологии UML, вычислительный эле
мент - это узел. Но так как в данной книге это слово используется для обоз
начения других вещей, все-таки будем использовать термин вычuслuтеЛЬНЬ/i
элемент.
40 • Глава 2. Обзор UML
- - _ ..._
refresh
- - |
- |
refresh |
|
- - - - - - - - - |
|||
|
- -
«appLication»
""' - - - - ' /"/, ,,
refresh
-- - --"" " ,,'"
Рис. 2.35. Диаграмма развертывания
Прямоугольникипо. внутри вычислительных элементов представляют собой ком поненты Компонент - это коллекция объектов, которые развертываются все вместе. На этой диаграмме каждый вычислительный элемент имеет два компонента: компонент DNS и компонент application.
Связи между компонентами обозначены пунктирными линиями. Как показано на рис. 2.35, пунктирные линии, помеченные словом refresh, свидетельству ют о том, что компоненты application отправляют сообщения компонентам
DNS.
Г Л А В А
Жизненный цикл
программного обеспечения
Эта книга посвящена шаблонам, используемым на стадии объектно-ориентиропо. ванногоВ проектирования, которая является частью жизненного цикла
этой главе сначала описывается жизненный цикл, а затем представлена ero
часть, связанная с объектно-ориентированным проектированием, выполняе мым при исследовании проблемы.
За время жизни программного продукта предпринимаются разнообразные дей ствия.
На рис. 3. 1 показана часть всех действий по развертыванию ПО для бизнеса, вы полняемых на этапе проектирования программноro продукта. На нем представ лены только некоторые общие действия, которые выполняются с цельюВ выя- нения контекста использования шаблонов, рассматриваемых в книге. книге описываются повторяющиеся шаблоны, используемые на протяжении той час ти жизненного цикла ПО, которая на рис. 3.1 помечена как (,Построение» .
Рис. 3. 1 демонстрирует очень четкие границы между действиями. В действи тельности границы не всегда являются такими точными. Иногда трудно опре делить, к какому этапу принадлежит определенное действие. Н е так важна точ ность границ, как понимание отношений между этими действиями.
Усилия, предпринимаемые на начальных этапах (например, определение тре бований или объектно-ориентированный анализ), за дают направление после
дующих действий, например, определяют ключевые ситуации использования
или объектно-ориентированное проектирование. Однако на этих более позд
них этапах возникает дефицит продуктов, п олученных на ранних стадиях. При
определении ситуации использования может оказаться, например, что выдви
гается неоднозначное или несовместимое требование. Необходимость измене
ния требований п риводит, главным образом, к необходимости изменения су
ществующих ситуаций использования или написания новых. Такие итерации вполне вероятны. Итерации, выполняемые на более поздних этапах, предпола
гают меньше изменений, чем итерации, реализуемые на более ранних стадиях.
Опиш ем некоторые действия , представленные на рис. 3. 1 . Описание прост предоставляет пользователю достаточную информацию об этих действияхMOry, тчтобbl
он понимал, каким образом описываемые в данной книге шаблоны при
меняться в рамках соответствующеro действия. Исследование проблемы, сле дующее за описанием, подразумевает более глубокое рассмотрение деЙстI3ИЙ.
Глава 3. Жизненный цикл программного обеспечения - 43
Определение ситуаций использования. Ситуация использования описывает по следовательность-событий, происходящих межцу системой и другими объектами (исполнителями actors) при определенных обстоятельствах. В результате раз работки ситуаций использования появляется более глубокое представление о требованиях, анализе или проектировании, составляющих основу ситуации использования.
Ключевые ситуации использования описывают события с точки зрения проблем ной области. Ситуации использования, описывающие события с точки зрения внутренней структуры программного продукта, называются реальными ситуа циями использования.
Ситуации использования, более всего приспособленные для уточнения требо ваний, представляют собой ключевые ситуации использования высокого уровня.
Высокий уровень таких ситуаций означает, что они исследуют принципы, на которых они основаны, и не пытаются добавлять дополнительные детали.
Создание прототипа. Целью этого действия является создание прототипа буду щего программного продукта, который может применяться для получения от кликов на готовяшийся проект. Результаты прототипирования MOryr быть ис пользованы для уточнения требований и ситуаций использования.
Следующие два этапа относятся к определению архитектуры системы высокого уровня. Цель этого действия заключается в определении основных компонен тов системы, которые являются логическим следствием первоначальных пред положений и их отношений.
Объектно-ориентированный анализ. Цель данного действия - выяснить, что будет делать описанный в проекте программный продукт и как он будет взаи модействовать с другими объектами своего окружения. В ходе анализа должна быть создана модель того, ЧТО будет делать ПО, н о не КАК оно это будет де
лать. Продукты объектно-ориентированного анализа моделируют ситуацию,
в рамках которой будет работать программный продукт, с точки зрения внеш
него наблюдателя. Сам по себе анализ не затрагивает всего происходящего
внутри программного продукта.
Объектно-ориентированное проектирование. Целью данного действия является определение внутренней структуры ПО. Продукты проектирования иденти
фицируют классы, образующие внутреннюю логику ПО. Они задают также
внутреннюю структуру классов и их взаимоотношения. На этапе объектно-ориентированного проектирования принимается больше
решений, чем на любом друтом. Поэтому в данной книге уделяется особое вни
Мание шаблонам, которые более всего подходят для объектно-ориентирован
ного проектирования, чем для любого другого вида деятельности.
Кодирование. На этом этапе пишется код, заставляющий ПО работать.
Тестирование. Результатом этого этапа является гарантия выполнения програм
Мным продуктом своих функций в соответствии с поставленными задачами.
«• Глава 3. ЖизнеННblЙ цикл программного обеспечения
Исследование проблемы
Рассмотрим ситуацию использования, которая включает проектирование и раз
работку системы учета рабочего времени служащих выдуманной компании
Henry's Food Market «(Продовольственная сеть Генри»). Некоторые обстоя тельства процесса разработки упрощены и сокращены. Задача данного иссле
дования состоит в определении места действия ситуации, демонстрирующего
применение шаблонов проектирования.
Бизнес-планирование
Здесь представлено упрощенное бизнес-планирование, описывающее мотива
цию и планирование, связанные с созданием системы учета рабочего времени служащих.
<.Продовольственная сеть Генри» состоит из пяти магазинов, товарного склада
ибулочной, которая производит выпечку, реализуемую через магазины. Боль
шинство служащих компании получает почасовую оплату. Рабочее время со трудников отслеживается системой учета времени. Приходя на работу, выходя на перерыв, возвращаясь с перерыва или уходя с работы, все служащие должны пропускать свои идентификационные карточки через устройство учета време ни, которое фиксирует рабочее время.
«Продовольственная сеть Генри» намерена расшириться и в течение двух лет увеличить количество своих магазинов с 5 до 21, открывая каждые три месяца
по два новых магазина. При этом возникает проблема: если компания Генри продолжает эксплуатировать прежнюю сисдлятему учета времени, то она должна будет нанять большее количество людей администрирования системы учета
времени. На данный момент каждую торговую точку должен обслуживать со трудник, который половину смены регистрирует рабочее время и обслуживает
систему учета времени этой точки. В функции регистратора входят следующие
действия• .
Он печатает отчеты, содержащие количество часов занятости каждого со
трудника на работе в течение последнего дня. Это позволяет контролерам
убедиться в том, что их подчиненные работали установленное количество
часов. Контролеры, просматриваюшие такие отчеты, чаще всего обнаружи
вают следующие нарушения:
служащие, уходящие на перерыв или с работы, не отметили время ухода;
коллеги отметили время прихода служащих, когда те опоздали на работу;
служащие отметили время прихода до начала своей рабочей смены, надеясь на
•сверхнормативного времени.
•Регистратор вносит изменения в систему учета рабочего времени.
Регистратор готовит еженедельные отчеты, в которых указано, сколько чаоплату
сов проработал каждый служащий, и отправляет эти отчеты в отдел платеж-