UML2 и унифицированный процесс. Джим арлоуайла нейштадтпрактический объектно ориентированныйанализ и проектированиеu
Скачать 6.08 Mb.
|
18.2. Отношения уровня проектирования Аналитические ассоциации должны быть уточнены до отношений уров ня проектирования, непосредственно реализуемых целевым ОО языком программирования. При переходе к проектированию необходимо уточнить отношения меж ду классами анализа и превратить их в отношения между проектными классами. Многие из выявленных при анализе отношений не могут 392 Глава 18. Уточнение отношений, выявленных при анализе Рис. 18.1. План главы 18.11.3. Классы ассоциации изучаем агрегацию изучаем композицию конкретизация отношений уточнение ассоциаций один к одному уточнение ассоциаций многие к одному уточнение ассоциаций один ко многим 18.2. Отношения уровня проекта 18.3. Агрегация и композиция 18.4. Семантика агрегации 18.5. Семантика композиции 18.5.1. Композиция и атрибуты 18.6. Как уточнять отношения уровня анализа 18.7. Ассоциации один к одному 18.8. Ассоциации многие к одному 18.9. Ассоциации один ко многим 18.10. Коллекции 18.10.1. Карта 18.13. Что мы узнали 18.12.2. Структурированные классы 18.12.1. Структурированные классификаторы 18.12. Изучение композиции с использованием структурированных классов 18.11. Конкретизированные отношения 18.11.1. Ассоциации многие ко многим 18.11.2. Двунаправленные ассоциации 18.3. Агрегация и композиция 393 быть реализованы как есть, их надо сделать таковыми. Например, ни один из широко распространенных ОО языков программирования не поддерживает двунаправленные ассоциации, классы ассоциации или ассоциации многие ко многим. Чтобы создать проектную модель, не обходимо определить, как должны быть реализованы эти ассоциации. Уточнение аналитических ассоциаций до ассоциаций уровня проекти рования включает несколько процедур: • уточнение ассоциаций до отношений агрегации или композиции в соответствующих случаях; • реализацию ассоциаций один ко многим; • реализацию ассоциаций многие к одному; • реализацию ассоциаций многие ко многим; • реализацию двунаправленных ассоциаций; • реализацию классов ассоциаций. Все ассоциации уровня проектирования должны обладать: • возможностью навигации; • кратностью на обоих концах. У всех ассоциаций уровня проектирования должно быть указано имя ассоциации или имя роли, по крайней мере, на целевом конце. 18.3. Агрегация и композиция При проектировании отношение ассоциация можно уточнить до агре гации или более строгой формы агрегации – композитной агрегации, если ассоциация имеет соответствующую семантику. Обычно компо зитную агрегацию называют просто композицией. Получить представление о семантических отличиях между двумя ти пами агрегации можно из обсуждения примеров, взятых из окружаю щего нас мира. • Агрегация – это свободный тип отношения между объектами – как между компьютером и его периферийным оборудованием. • Композиция – это очень строгий тип отношения между объектами – как между деревом и его листьями. Из примера, приведенного на рис. 18.2, можно сделать вывод, что компьютер очень слабо взаимосвязан со своим периферийным обору дованием. Периферийные устройства могут появляться и исчезать, могут совместно использоваться с другими компьютерами. Они не «принадлежат» конкретному компьютеру. Это пример агрегации. На против, дерево тесно взаимосвязано со своими листьями. Листья при надлежат только одному дереву, ими нельзя поделиться с другими де ревьями, и когда дерево умирает, листья умирают вместе с ним. Это пример композиции. 394 Глава 18. Уточнение отношений, выявленных при анализе Очень полезно помнить об этих простых аналогиях при дальнейшем более подробном рассмотрении семантики агрегации и композиции. 18.4. Семантика агрегации Агрегация – это тип отношения целое часть, в котором агрегат образу ется многими частями. В отношении целое часть один объект (целое) использует сервисы другого объекта (части). По существу, целое явля ется доминантной и управляющей стороной отношения, тогда как часть просто обслуживает запросы целого и, следовательно, играет бо лее пассивную роль. Действительно, если навигацию можно осуществ лять только от целого к части, последняя даже не знает, что является частью целого. Рассмотрим конкретный пример агрегации (рис. 18.3). Мы видим сле дующее: • компьютер (класс Computer) может быть присоединен к 0 или более принтерам (класс Printer); • в любой момент времени принтер соединен с 0 или 1 компьютером; • в ходе времени конкретный принтер может использоваться многи ми компьютерами; • принтер может существовать, даже если не подключен ни к одному компьютеру; • принтер фактически не зависит от компьютера. Композиция Агрегация UML определяет два типа ассоциации Некоторые объекты тесно взаимосвязаны, как дерево и его листья Некоторые объекты слабо взаимосвязаны друг с другом, как компьютер и его периферийное оборудование Рис. 18.2. Два типа ассоциации в UML часть целое, или агрегат агрегация Computer Printer 0..1 0..* Рис. 18.3. Пример агрегации 18.4. Семантика агрегации 395 Агрегация – это отношение целое часть. Семантику агрегации можно подытожить следующим образом: • агрегат может существовать как независимо от частей, так и вместе с ними; • части могут существовать независимо от агрегата; • агрегат является в некотором смысле неполным в случае отсутст вия некоторых частей; • части могут принадлежать одновременно нескольким агрегатам. Агрегация транзитивна. Рассмотрим пример на рис. 18.4. Транзитив ность означает, что если C является частью B, и B является частью A, тогда C также является частью A. Агрегация транзитивна. Агрегация асимметрична. Это означает, что объект никогда – ни пря мо, ни косвенно – не может быть частью самого себя. Это ограничивает способы использования агрегации в моделях. В примере на рис. 18.5 по казано, что объекты Product могут состоять из других объектов Product. В данном случае ошибки нет, потому что это разные объекты, и огра ничение асимметрии не нарушено. Агрегация транзитивна: если C является частью B, и B является частью A, тогда C также является частью A A B C Рис. 18.4. Агрегация транзитивна рефлексивная агрегация циклы НЕдопустимы a:Product b:Product Product c:Product d:Product * * Рис. 18.5. Ограничение асимметрии для агрегации не нарушено, т. к. здесь представлены разные объекты Product 396 Глава 18. Уточнение отношений, выявленных при анализе Агрегация асимметрична. Объект никогда не может быть частью самого себя. Продолжим рассмотрение рис. 18.5. Иногда может понадобиться смо делировать ситуацию, когда между объектами d и a существует связь, как показано на рисунке. Такое может случиться, если объекту d необ ходимо осуществить обратный вызов и использовать некоторые сер висы объекта агрегата a. Но как это смоделировать на диаграмме клас сов? Рефлексивная агрегация (reflexive aggregation) с классом Product не подходит, потому что согласно ограничению асимметрии для агре гации объект a не может быть частью самого себя ни прямо, ни косвен но. Поэтому для обработки связи между объектами d и a необходимо использовать рефлексивную неуточненную ассоциацию класса Product с самим собой, как показано на рис. 18.6. Ассоциация симметрична. Объект может быть ассоциирован с самим собой. На рис. 18.7 показан другой типичный пример агрегации. Домашний компьютер (целое) может быть смоделирован как набор частей. Эти части довольно слабо взаимосвязаны с целым. Их можно переносить с компьютера на компьютер или использовать совместно с другими компьютерами, поэтому в этой модели применима семантика агрега ции. Согласно этой модели домашний компьютер можно рассматри вать как совокупность следующих частей: Mouse (мышь), Keyboard (кла виатура), CPU (центральный процессор), Monitor (монитор) и два объек та Speaker (колонка). CPU, в свою очередь, может быть смоделирован как совокупность различных аппаратных компонентов, таких как RAM (ОЗУ), HardDrive (жесткий диск) и т. д. a:Product d:Product Product * * c:Product b:Product рефлексивная агрегация Рис. 18.6. Связь между объектами a и d реализована посредством рефлексивной неуточненной ассоциации 18.5. Семантика композиции 397 18.5. Семантика композиции Композиция – более строгая форма агрегации. Она имеет сходную (но более ограниченную) семантику. Как и агрегация, это отношение це лое часть, являющееся как транзитивным, так и асимметричным. Ключевое различие между агрегацией и композицией в том, что в ком позиции у частей нет независимой жизни вне целого. Более того, в ком позиции каждая часть принадлежит максимум одному и только одно му целому, тогда как при агрегации часть может совместно использо ваться несколькими целыми. Композиция – это строгая форма агрегации. В примере на рис. 18.8 объекты Button (кнопка) не могут существовать независимо от владеющего ими объекта Mouse. Если уничтожается объект Mouse, уничтожаются и принадлежащие ему объекты Button, потому что они являются его неотъемлемой частью. Каждый объект Button может принадлежать только одному объекту Mouse. Так же и ли стья на деревьях – жизнь листа определяется жизнью дерева, и лист может принадлежать только одному дереву. * 1..* 1 2 1 1 1 connectedTo connectedTo HomeComputer 2 1 1 1 1 1 1 1 CDRom HardDrive FloppyDrive RAM GraphicsCard SoundCard Speaker Monitor CPU Keyboard Mouse Рис. 18.7. Типичный пример агрегации: компьютер как совокупность его частей Button Mouse 1 1..4 часть композит всегда 0..1 или 1 композиция Рис. 18.8. Пример композиции 398 Глава 18. Уточнение отношений, выявленных при анализе Композит имеет исключительное право владения и ответственности за свои части. Резюмировать семантику композиции можно следующим образом: • одновременно части могут принадлежать только одному композиту – совместное владение частями невозможно; • композит обладает исключительной ответственностью за все свои части; это означает, что он отвечает за их создание и уничтожение; • композит может высвобождать части, передавая ответственность за них другому объекту; • в случае уничтожения композита он должен или уничтожить все свои части, или передать ответственность за них другому объекту. Поскольку композит обладает исключительной ответственностью за жизненный цикл и управление своими частями, то при создании объ ект композита часто создает и свои части. Аналогично при уничтоже нии композита он должен уничтожить все свои части или организо вать их передачу другому композиту. Несмотря на то, что существуют и иерархии, и сети рефлексивной аг регации, для рефлексивной композиции возможны только иерархии. В этом состоит еще одно отличие между агрегацией и композицией, которое объясняется тем, что в композиции объект часть в любой мо мент времени может быть частью только одного композита. 18.5.1. Композиция и атрибуты Часть композита эквивалентна атрибуту. Рассматривая семантику композиции, можно заметить, что она очень похожа на семантику атрибутов. Жизненный цикл в обоих случаях контролируется владельцами. И части, и атрибуты не могут независи мо существовать вне своих владельцев. В сущности, атрибуты – это точный эквивалент отношения композиции между классом композита и классом атрибута. Тогда зачем нужны два способа описания одного и того же? На это есть две причины: • Типом атрибута может быть простой тип данных. В некоторых гиб ридных ОО языках программирования, таких как C++ и Java, есть простые типы, например int и double, которые не являются класса ми. Их можно было бы моделировать как классы, обозначенные стереотипом «primitive», но это загромождало бы модель. Простые типы всегда должны моделироваться как атрибуты. • Существуют определенные, широко используемые утилитные клас сы, такие как Time, Date и String. Если бы каждый раз приходилось моделировать эти классы с помощью отношения композиции класса 18.6. Как уточнять отношения уровня анализа 399 с самим собой, очень скоро модели стали бы абсолютно непонятны ми. Намного лучше моделировать такие классы как атрибуты. Вывод состоит в следующем: если имеется простой тип, или утилит ный класс, или даже класс, который не стоит явно показывать в моде ли, поскольку он не представляет особого интереса либо от него мало пользы, необходимо рассмотреть возможность применения атрибута, а не отношения композиции. Здесь нет никакого конкретного и твер дого правила, но главное, о чем надо всегда помнить, – это понятность, полезность и удобочитаемость модели. 18.6. Как уточнять отношения уровня анализа При анализе использовались простые ассоциации без какого либо по дробного рассмотрения семантики отношения (или того, каким обра зом отношение должно быть реализовано). Однако при проектирова нии необходимо всегда пытаться достичь максимальной конкретиза ции и уточнить ассоциации до одного из отношений агрегации везде, где это возможно. Фактически ассоциация должна использоваться в проектировании, только если в противном случае в схеме агрегации образуется цикл (см. раздел 18.4). Такая ситуация встречается редко, поэтому большинство аналитических ассоциаций превращаются или в агрегацию, или в композицию. Аналитические ассоциации должны быть уточнены до одного из отно шений агрегации везде, где это возможно. После того как принято решение о применении агрегации или компо зиции, необходимо действовать следующим образом: • добавить в ассоциации кратности и имена ролей, если они отсутст вуют; • выбрать, какой конец ассоциации является целым, а какой – частью; • посмотреть на кратность связи со стороны целого; если это 0..1 или 1, вероятно , можно использовать композицию; в противном случае должна использоваться агрегация; • добавить возможность навигации от целого к части – ассоциации уровня проектирования должны быть однонаправленными. Таким образом, происходит уточнение ассоциации до агрегации или композиции. Если кратности целого или части больше 1, необходимо принять реше ние, как это будет реализовываться. Это второй шаг уточнения. 400 Глава 18. Уточнение отношений, выявленных при анализе 18.7. Ассоциации один к одному Практически всегда ассоциация один к одному превращается в компо зицию. По сути, ассоциация один к одному подразумевает настолько строгое отношение между двумя классами, что зачастую стоит рассмот реть возможность их объединения в один класс без нарушения правил проектирования для проектных классов (раздел 17.5). Если классы нельзя объединить, отношение один к одному уточняется до компози ции, как показано на рис. 18.9. Обычно ассоциации один к одному подразумевают композицию. Также можно было бы рассмотреть возможность превращения Party Identifier (идентификатор партии) в атрибут класса Party (партия), если PartyIdentifier не является особо важным классом. Это, конечно, упро щает диаграмму (рис. 18.10), но имеет и недостаток: нельзя показать атрибуты или операции, принадлежащие классу PartyIdentifier. 18.8. Ассоциации многие к одному В ассоциации многие к одному целое имеет кратность «много», а крат ность части равна 1. Party PartyIdentifier Party PartyIdentifier 1 1 1 1 «trace» анализ проектирование Рис. 18.9. Ассоциация один к одному уточняется до композиции анализ проектирование 1 1 Party Party PartyIdentifier id:PartyIdentifier «trace» Рис. 18.10. Класс PartyIdentifier превращен в атрибут класса Party 18.9. Ассоциации один ко многим 401 Поскольку со стороны целого кратность равна «много», сразу понят но, что композиции невозможна, потому что часть используется со вместно многими целыми. Но, вероятно, возможна агрегация. Здесь необходимо провести проверку на наличие циклов в схеме агрегации (см. раздел 18.4). Если таковых не обнаружено, аналитическую ассо циацию можно уточнять до агрегации, как показано на рис. 18.11. Как видно из этого примера, один объект Currency (валюта) совместно используется многими объектами Money (деньги). Это абсолютно верно отражает отношение между деньгами и валютой: деньги – это сумма в некоторой валюте. Намного более полную модель денег можно найти в книге [Arlow 1]. Ассоциации многие к одному подразумевают агрегацию, если в схеме агрегации нет цикла. 18.9. Ассоциации один ко многим В ассоциации один ко многим со стороны части присутствует коллек ция объектов. Чтобы реализовать такое отношение, необходимо ис пользовать или поддержку коллекций, предоставляемую языком реа лизации, или классы коллекции. Большинство ОО языков программирования имеют минимальную встроенную поддержку коллекций объектов. В сущности, большинство языков предлагают только массивы. Массив – это индексированная коллекция объектных ссылок, обычно ограниченная некоторым макси мальным размером. Преимущество встроенных массивов, как правило, состоит в их высокой производительности. Однако это преимущество нивелируется их малой гибкостью в сравнении с другими типами кол лекций. Классы коллекции обычно характеризуются намного большей мощью и гибкостью, чем массивы. Они предлагают разнообразные семантики, в которых массив является лишь одним из возможных вариантов. Да лее вся глава посвящена классам коллекций. целое часть анализ проектирование Currency Currency Money Money 1 «trace» 1 * * |