Гради Буч - Объектно-ориентированный анализ и проектирование с примерами приложений на С++ (1158635), страница 50
Текст из файла (страница 50)
Посылкасинхронизированного сообщения эквивалентна механизму свиданий задач вязыке Ada (rendezvous). В случае сообщения isReady() клиент отложитсообщение, если сервер н сможет его немедленно обработать. Сообщениеrestart() будет отложено клиентом, если сервер не может его обработать зауказанный промежуток времени.В каждом из трех последних случаев клиент должен ждать, покасервер обработает сообщение, или отложить пересылку, после чего можетбыть возобновлено управление. Сообщение failure имеет другуюсемантику.
Это пример несинхронизированного сообщения, котороеподразумевает, что клиент посылает событие серверу для обработки, серверставит сообщение в очередь, а клиент продолжает работать. Такиеасинхронные сообщения сродни прерываниям.Расписание. В программах, имеющих ограничения по времени, важноотслеживать чистое время с момента начала каждого сценария. Дляобозначения относи тельного времени (в секундах) мы ставим знак плюс.Например, на рис.
5-29 сообщение startUp() вызывается в первый раз спустя5 секунд после начала сценария далее, через 6.5 секунд после начала сценарияследует сообщение ready() и затем, спустя 7 секунд после начала сценария, сообщение turnOn().СпецификацииКак и для диаграмм классов, за каждым элементом диаграммыобъектов могут стоять спецификации. Спецификации объектов и их связей ненесут никакой иной информации, кроме уже описанной. С другой стороны,спецификации диаграмм объектов как целого могут сообщить кое-что важное.Как упоминалось ранее, каждая диаграмма объектов существует в контексте.В спецификации контекст указывается следующим образом:Context: глобальный | категория | класс | операцияВ частности, область видимости диаграммы объектов может бытьглобальной, или в контексте указанной категории классов, класса илиоперации (включая, как методы, так и свободные подпрограммы).Рис.
5-29. Расписание5.5. Диаграммы взаимодействияСущественное: объекты и их взаимодействияДиаграмма взаимодействии используется, чтобы проследитьвыполнение сценария в том же контексте, что и диаграмма объектов.15 Визвестной степени диаграмма взаимодействия есть просто другой способпредставления диаграммы объектов. Например, на рис. 5-30 мы видимдиаграмму взаимодействия, которая дублирует большую часть семантикидиаграммы объектов, показанной на рис.
5-25. Преимущество диаграммывзаимодействий в том, что на ней легче читается порядок посылки сообщений,а преимущество диаграммы объектов в том, что она лучше подходит длямногих объектов со сложными вызовами и допускает включение другойинформации: связи, значения атрибутов, роли, блок-схемы и видимость. Таккак оба типа диаграмм имеют неоспоримые достоинства, мы пользуемся внашем методе обоими.16Диаграммы взаимодействия не вводят новых понятий илиобозначений.
Скорее, они берут существенные элементы диаграммы объектови перестраивают их. Как показывает рис. 5-30, диаграмма взаимодействийвнешне напоминает таблицу. Имена объектов диаграммы взаимодействий (теже, что и на диаграмме объектов) записываются горизонтально в верхней еестроке. Под каждым из них рисуется вертикальная пунктирная линия.Отправления сообщений (которые могут обозначать события или вызовыопераций) показываются горизонтальными стрелками, с тем же синтаксисом иобозначениями синхронизации, что и на диаграмме объектов. Линия,обозначающая посылку сообщения, проводится от вертикали клиента квертикали сервера.
Первое сообщение показывается на самом высоком уровне,15Эти диаграммы обобщают диаграммы трассировки событий Румбаха и диаграммывзаимодействий Джекобсона [15].16Диаграммы объектов и диаграммы взаимодействий настолько близки по семантике,что инструментальные средства могут генерировать одну диаграмму из другой сминимальной потерей информации.второе ниже и т.
д., таким образом отпадает надобность в их порядковыхномерах.Рис 5-30Диаграммы взаимодействий часто лучше диаграмм объектов передаютсемантику сценариев на ранних этапах жизненного цикла разработки, когдаеще не идентифицированы протоколы отдельных классов. Как мы расскажем вследующей главе, в начале разработки диаграммы взаимодействий обычносконцентрированы скорее на событиях, чем на операциях, потому что событияпомогают определитьРис. 5-31. Пояснения и переход управленияграницы системы. Когда же уточнились структуры классов, акцент смещаетсяк диаграммам объектов, семантика которых более выразительна.Дополнительные понятияДиаграммы взаимодействия концептуально очень просты, но есть двапоясняющих элемента, которые позволяют сделать их более выразительнымипри наличии сложных шаблонов взаимодействия.Пояснения.
Для сложных сценариев, использующих условия илиитерации, диаграмма объектов может быть дополнена пояснениями. Какпоказано на примере (рис. 5-31), пояснения могут быть подписаны к любомусообщению слева от диаграммы на соответствующем уровне простымтекстом, с элементами структуризации, или с использованием синтаксисаязыка реализации.Передача управления. Ни простейшие диаграммы объектов, нидиаграммы взаимодействий не показывают передач управления.
Например,если мы показали, что объект А посылает сообщения X и Y другим объектам,то остается неясным, являются ли сообщения X и Y независимымисообщениями из А или они были вызваны как части некоторого объемлющегосообщения Z. Как показано на рис. 5-31, мы можем нарисовать навертикальной линии каждого объекта полоски, показывающие периоды, когдауправление находится в этом объекте. На этом примере мы видим, что всемруководит анонимный экземпляр класса GardeningPlan, который, выполняяклиматический план, вызывает другие методы, которые, в своюочередь,вызывают следующие методы, и, в конце концов, управлениевозвращается обратно к нему же.5.6. Диаграммы модулейСущественное: модули и их зависимостьДиаграмма модулей показывает распределение классов и объектов помодулям в физическом проектировании системы.
Каждая отдельнаядиаграмма модулей представляет некоторый ракурс структуры модулейсистемы. При разработке мы используем диаграмму модулей, чтобы показатьфизическое деление нашей архитектуры по слоям и разделам.Некоторые языки, особенно Smalltalk, не имеют ничего подобногофизической архитектуре, сформированной модулями; в таких случаяхдиаграммы модулей не употребляют.Основными элементами диаграммы модулей являются модули и ихзависимости.Модули. На рис. 5-32 сведены обозначения различных типов модулей.Первые три значка - это файлы, различающиеся своими функциями.
Значокглавной программы обозначает файл, содержащий корневую программу. ВC++, например, это соответствовало бы некоторому файлу с расширением.срр, содержащему привилегированную функцию-неэлемент, называемуюmain. Обычно существует ровно один такой модуль на программу. Значокописания и значок тела обозначают файлы, которые содержат, соответственно,описания и реализации. В C++, например, модуль описаний соответствуетзаголовочному файлу с расширением .h, а модуль тела - файлу с текстомпрограммы с расширением .срр.Рис. 5-32.
Значки модулей и подсистемСмысл значка подсистемы мы раскроем в следующем разделе. Каждыймодуль должен иметь имя; обычно это имя соответствующего физическогофайла в каталоге проекта. Как правило, такие имена пишутся без суффиксов,которые опознаются по типу значка. Если имя чересчур длинно, мы, какобычно, либо сокращаем его, либо расширяем значок. Каждое полное имяфайла должно быть уникально в содержащей его подсистеме. В соответствиис правилами конкретной среды разработки, мы можем наложить ограниченияна имена, такие, как условие на префиксы или требование уникальности всистеме.Каждый модуль содержит либо описание, либо определение классов иобъектов, а также другие конструкции языка.
По идее, "раскрыв" значокмодуля на диаграмме, мы должны попасть внутрь соответствующего файла.Рис. 5-33. Диаграмма модулей гидропонной системыЗависимости. Единственная связь, которая может существоватьмежду двумя модулями, - компиляционная зависимость - представляетсястрелкой, выходящей из зависимого модуля. В C++, например, мы указываемтакую зависимость директивой #include. Аналогично, в Adaкомпиляционная зависимость указывается фразой with. В множествекомпиляционных зависимостей не могут встречаться циклы.
Чтобыопределить частичную упорядоченность компиляций, достаточно выполнитьчастичное упорядочение структуры модулей системы.Пример. На рис. 5-33 показан пример обозначений модулей, вархитектуре системы тепличного гидропонного хозяйства. Мы видим здесьшесть модулей. Два из них, climatedefs и cropdefs, являются толькоописаниями и служат для предоставления общих типов и констант.
Остальныечетыре включают в себя и тела, и описания: это типичный стиль построениядиаграмм модулей, так как описания и тела очень тесно связаны. На рисункеэти две части совмещены, и зависимость тела от описания получиласьскрытой, хотя реально она существует. Также оказалось скрытым имя тела, но,по нашему соглашению, имена тела и описания различаются лишьсуффиксами (.срр и .h).Зависимости на этой диаграмме предполагают частичноеупорядочение компиляции. Например, тело модуля climate зависит отописания heater, которое, в свою очередь, зависит от описанияclimatedefs.Существенное: подсистемыКак объяснялось в главе 2, большие системы могут быть разложены нанесколько сотен, если не тысяч, модулей.
Пытаться разобраться в физическойархитектуре такой системы без ее дополнительного структурирования почтибезнадежно. На практике разработчики стремятся следовать неформальномусоглашению собирать связанные между собой модули в структуры типакаталогов. По этим соображениям мы введем понятие подсистемы надиаграмме модулей.
Подсистемы представляют собой совокупностилогически связанных модулей, примерно как категория классов представляетсовокупность классов.Подсистемы. Подсистемы служат частями физической моделисистемы. Подсистема - это агрегат, содержащий другие модули и другиеподсистемы. Каждый модуль в системе должен жить в одной подсистеме илинаходиться на самом верхнем уровне.На рис. 5-32 показано обозначение подсистемы. Как и модуль,подсистема должна быть именованной. Имена подсистем подчиняются тем жеправилам, что и имена модулей, хотя полное имя подсистемы обычно несодержит суффиксов.Некоторые модули, содержащиеся в подсистеме, могут бытьобщедоступны, то есть экспортированы из системы и видимы снаружи.Другие модули могут быть частью реализации подсистемы и непредназначаться для использования внешними модулями.
По соглашению,каждый модуль подсистемы считается общедоступным, если явно не указанообратное. Ограничение доступа к модулям реализации достигаетсяиспользованием тех же обозначений, что и для ограничения доступа вкатегории классов.Подсистема может зависеть от других подсистем и модулей; модульможет также зависеть от подсистемы. Для единообразия мы используемпрежнее обозначение зависимости. Система имеет один высший уровень,состоящий из подсистем и модулей высшего уровня абстракции. По егодиаграмме разработчик получает представление об общей физическойархитектуре системы.Пример. На рис.