UML2 и унифицированный процесс. Джим арлоуайла нейштадтпрактический объектно ориентированныйанализ и проектированиеu
Скачать 6.08 Mb.
|
Рис. 18.11. Ассоциация многие к одному уточняется до агрегации 402 Глава 18. Уточнение отношений, выявленных при анализе 18.10. Коллекции Класс коллекции – это класс, экземпляры которого специализируют ся на управлении коллекциями других объектов. В большинстве язы ков программирования есть стандартные библиотеки классов коллек ций (и других утилит). Классы коллекции – это классы, экземпляры которых содержат коллек ции объектов. Одним из ключей к отличному ОО проектированию и реализации явля ется совершенное владение классами коллекций. У всех таких классов есть операции для: • добавления объектов в коллекцию; • удаления объектов из коллекции; • извлечения ссылки на объект, находящийся в коллекции; • обход коллекции, т. е. проход по коллекции от первого объекта до по следнего. Существует много типов коллекций, по разному обрабатывающих кол лекции объектов. Важным аспектом ОО проектирования и реализации является правильный выбор типа коллекции (обсуждается далее). В качестве примера использования коллекций на рис. 18.12 показана ассоциация один ко многим уровня анализа, реализованная с помо щью класса коллекции Vector. Это класс стандартной библиотеки Java java.util. Как правило, между целым (классом Order (заказ)) и классом Vector устанавливается отношение композиции, поскольку Vector обыч но является всего лишь частью реализации целого и не может сущест вовать вне него. Однако между классом Vector и его частями (OrderLine (строка заказа)) может существовать отношение агрегации или компо зиции. Если целое несет ответственность за жизненный цикл частей, как в данном примере, можно использовать композицию. В противном случае должна использоваться агрегация. Order OrderLine Order OrderLine 1 * 1 Vector 1 * 1 целое часть «trace» анализ проектирование Рис. 18.12. Реализация ассоциации один ко многим с помощью класса коллекции Vector 18.10. Коллекции 403 Классы коллекции реализуют ассоциации один ко многим. С точки зрения моделирования с использованием коллекций сущест вует четыре фундаментальные стратегии: • Класс коллекции моделируется явно; этот вариант представлен на рис. 18.12. Его преимущество в чрезвычайной детализации, однако есть и большой недостаток – загроможденность проектной модели. Если ассоциация один ко многим заменяется классом кол лекции, модель быстро становится очень раздутой. Выбор класса коллекции обычно является тактическим решением реализации, и право это сделать можно передать программистам. Мы рекомен дуем заменять ассоциации один ко многим конкретными класса ми коллекций, только если выбор коллекции является стратегиче ски важным. • Инструментальному средству моделирования сообщается о том, как будет реализовываться каждая конкретная ассоциация один ко многим. Многие инструменты моделирования, генерирующие код, позволяют назначать конкретный класс коллекции для каж дой ассоциации один ко многим. Обычно это осуществляется путем добавления в ассоциацию помеченных значений, определяющих свойства генерации кода для данного отношения. Этот подход ото бражен на рис. 18.13. Здесь на соответствующем конце отношения указано свойство {Vector}. Обратите внимание, что используется толь ко именная часть помеченного значения – часть «значение» в дан ном случае является излишней. Опасайтесь «переусердствовать» при использовании коллекций. • Путем добавления свойства к отношению определяется семантика коллекции, но не указывается какой либо конкретный класс реа лизации (рис. 18.14). При использовании коллекций важно не «пе реусердствовать». Как говорилось, фактически используемый тип коллекции – часто тактическое, а не стратегическое решение, кото рое может быть принято программистами во время реализации. Order OrderLine 1 {ordered}* Рис. 18.14. Добавление в ассоциацию свойства без указания конкретного класса реализации Order OrderLine 1 {Vector}* Рис. 18.13. Добавление в ассоциацию помеченного значения 404 Глава 18. Уточнение отношений, выявленных при анализе Этот вариант хорош тем, что сохраняется лаконичность модели, и программистам могут быть предоставлены подсказки по поводу того, какой класс коллекции должен использоваться. Однако та кой подход обычно исключает автоматическую генерацию кода. • Уточнением отношения один ко многим до классов коллекций не занимаются – решение этой задачи передается программистам. UML предоставляет стандартные свойства, которые могут применять ся к кратностям для обозначения требуемой семантики коллекции. Они представлены в табл. 18.1. Упорядоченность определяет, как располагаются элементы в коллек ции: в строгом порядке относительно друг друга или нет. Уникаль ность определяет единичность каждого объекта коллекции. Для отно шения один ко многим по умолчанию применяется семантика {unor dered, unique} ({неупорядоченный, уникальный}). Таблица 18.1 Например, если необходима упорядоченная коллекция объектов Order Lines, то изображенное на рис. 18.13 можно показать, как представле но на рис. 18.14. Сочетания свойств упорядочения и уникальности создают набор кол лекций, перечисленных в табл. 18.2. Эти коллекции являются частью OCL (объектный язык ограничений) (см. главу 25), хотя аналогичный набор коллекций есть во всех языках программирования. Таблица 18.2 Стандартное свойство Семантика {ordered} Существует строгий порядок расположения элемен тов коллекции. {unordered} Элементы в коллекции располагаются в произволь ном порядке. {unique} Все элементы коллекции уникальны – один и тот же объект появляется в коллекции максимум один раз. {nonunique} В коллекции допускается дублирование элементов. Свойство Коллекция OCL {unordered, nonunique} Bag (мультимножество) {unordered, unique} Set (множество) {ordered, unique} OrderedSet (упорядоченное множество) {ordered, nonunique} Sequence (последовательность) 18.10. Коллекции 405 18.10.1. Карта Карты оптимизированы с целью быстрого получения значения по ключу. Еще один очень полезный тип класса коллекции – карта (map). Иногда его называют словарем (dictionary). 1 Эти классы немного похожи на таблицу базы данных с двумя столбцами – ключ и значение. Карты спроектированы таким образом, чтобы по заданному ключу можно бы ло быстро найти соответствующее значение. Если необходимо хра нить коллекции объектов, доступ к которым осуществляется по значе нию уникального ключа, или необходимо создать индексы быстрого доступа в другие коллекции, карта – оптимальное решение. Обычно работа карты заключается в обслуживании набора узлов, где каждый узел указывает на два объекта – объект ключ и объект значе ние. Они оптимизированы так, чтобы быстро находить объект значе ние по заданному объекту ключу. На рис. 18.15 показано упрощенное представление Java класса HashMap. Поиск значения (по заданному ключу) осуществляется очень быстро, по скольку коллекция проиндексирована с использованием хеш таблицы. В UML нет стандартного свойства для обозначения карты, и карты не являются частью OCL. Если в проектной модели необходимо обозначить применение карты, указывается конкретный тип коллекции (напри мер, {HashMap}) или используется следующее помеченное значение: {map имяКлюча} Если принято решение использовать это нестандартное обозначение, в модель необходимо добавить поясняющее примечание! 1 Еще известно как «ассоциативный массив». – Примеч. науч. ред. value3 key3 node3 value2 key2 node2 value1 key1 node1 m:HashMap Рис. 18.15. Пример карты 406 Глава 18. Уточнение отношений, выявленных при анализе 18.11. Конкретизированные отношения Некоторые типы отношений являются исключительно артефактами анализа и не поддерживаются напрямую ни одним из широко исполь зуемых ОО языков программирования. Процесс реализации таких от ношений уровня анализа называют конкретизацией (reification) (т. е. превращение в нечто конкретное). Конкретизации подвергаются сле дующие отношения уровня анализа: • ассоциации многие ко многим; • двунаправленные ассоциации; • классы ассоциации. 18.11.1. Ассоциации многие ко многим Ни один из широко используемых ОО языков программирования не поддерживает напрямую ассоциации многие ко многим (хотя некото рые объектные базы данных все таки их поддерживают). Поэтому эти ассоциации необходимо конкретизировать в обычные классы, отноше ния агрегации, композиции и зависимости. При анализе такие вопро сы, как владение и навигация, могли бы оставаться неясными, но в проектировании такая неопределенность невозможна. Это тот слу чай, когда сначала надо решить, какая из сторон ассоциации многие ко многим является целым, а затем применять соответственно агрега цию или композицию. В примере на рис. 18.16 отношение allocation (распределение) было конкретизировано в класс Allocation. Это превращает ассоциацию мно гие ко многим в два отношения агрегации. Исходя из требований, предъявляемых к системе, было принято решение, что Resource (ре сурс) – это целое. Система главным образом занимается управлением потоками работ, ассоциированными с Resource, т. е. является ресурсо центричной. Однако если бы система была задаче центричной, целым был бы сделан объект Task (задача), что изменило бы направление отно шений, представленных на рисунке. Было также решено возложить ответственность за жизненный цикл объектов Allocation на Resource, и поэтому используется отношение ком позиции. Resource Task Resource Task * 1 * 1 Allocation * allocation * «trace» анализ проектирование Рис. 18.16. Ассоциация многие ко многим конкретизирована в класс Allocation 18.11. Конкретизированные отношения 407 Если система пытается представить обе точки зрения, ее можно было бы назвать ориентированной на распределение ресурсов. Тогда был бы введен новый объект (возможно, AllocationManager (менеджер распреде ления)), обслуживающий список объектов Allocation, каждый объект которого указывает как на объект Resource, так и на объект Task. 18.11.2. Двунаправленные ассоциации Часто необходимо смоделировать обстоятельства, в которых объект а класса А использует сервисы объекта b класса В, и объекту b необходи мо делать обратный вызов и использовать сервисы объекта а. В качест ве примера можно привести элемент управления GUI Window с одним или более объектами Button, где каждому объекту Button надо выпол нять обратный вызов и использовать сервисы Window, которому они принадлежат. При анализе все просто – такая ситуация моделируется как единствен ная двунаправленная ассоциация. Однако ни один из широко исполь зуемых ОО языков программирования реально не поддерживает дву направленные ассоциации. Поэтому при проектировании такая ассо циация должна быть конкретизирована в две однонаправленные ассо циации или зависимости, как показано на рис. 18.17. При моделировании обратных вызовов необходимо помнить об асим метрии агрегации и композиции – объект никогда – ни прямо, ни кос венно – не может быть частью самого себя. Это значит, что если класс А имеет отношение агрегации или композиции с классом В, обратный вызов от В к А должен быть смоделирован как неконкретизированная ассоциация. Если бы между B и A было применено отношение агрега ции, объект b был бы частью (через композицию или агрегацию) объек та а, и объект а был бы частью (через агрегацию) объекта b. Такое зам кнутое владение, конечно же, нарушает асимметричность агрегации. Двунаправленные ассоциации также имеют место тогда, когда целое передает ссылку на себя в качестве параметра одной из операций части или когда часть в одной из своих операций создает экземпляр целого. В этих случаях необходимо использовать отношение зависимости от части к целому, а не ассоциацию. A A B B 1 1 * * 1 * «trace» «trace» анализ проектирование Рис. 18.17. При проектировании двунаправленная ассоциация конкретизируется в две однонаправленные ассоциации 408 Глава 18. Уточнение отношений, выявленных при анализе 18.11.3. Классы ассоциации Классы ассоциации – исключительно аналитические артефакты, ко торые напрямую не поддерживаются ни одним из широко используе мых ОО языков программирования. Таким образом, они не имеют пря мого аналога в проектировании и должны быть удалены из проектной модели. Класс ассоциация конкретизируется в обычный класс, а для отраже ния его семантики используется сочетание ассоциации, агрегации, композиции или даже зависимости. Это может потребовать наложе ния ограничений на модель. Принимается решение, какая из сторон ассоциации является целым, и соответственно этому используется композиция, агрегация и возможность навигации. Пример показан на рис. 18.18. Обратите внимание, что при конкретизации класса ассоциации теря ется его семантика, которая гласит, что объекты на каждом конце класса ассоциации должны формировать уникальную пару (см. раз дел 9.4.5). Однако, как показано на рис. 18.18, добавив примечание, содержащее соответствующее ограничение, эту семантику можно без труда восстановить. Person Company Person Company * 1 * 1 Job * salary:double Job salary:double {каждый человек (Person) в данной компании (Company) может занимать только одну должность (Job)} * «trace» анализ проектирование Рис. 18.18. Пример конкретизации класса ассоциации 18.12. Изучение композиции с использованием структурированных классов 409 18.12. Изучение композиции с использованием структурированных классов До сих пор мы брали отношения, выявленные при анализе, и превраща ли их в одно или более отношений уровня проектирования. В этом со стоит основная деятельность в уточнении отношений уровня анализа. Однако UML 2 также позволяет анализировать отношение между со ставным классификатором и его частями. Это может быть важной ча стью деятельностей UP Проектирование класса, Проектирование прецедента и Проектирование подсистемы, поскольку позволяет сосредоточить вни мание на внутренних действиях одного из этих классификаторов. Ос новным понятием здесь является структурированный классификатор, который рассматривается в следующем разделе. 18.12.1. Структурированные классификаторы Структурированный классификатор – это классификатор, имеющий внут реннюю структуру. Структурированный классификатор (structured classifier) – это просто классификатор (такой как класс), имеющий внутреннюю структуру. Эта структура моделируется как части, объединенные с помощью со единителей. Взаимодействие структурированного классификатора с его окружением моделируется его интерфейсами и портами, но мы отложим их обсуждение до главы 19. Часть – это роль, которую могут выполнять один или более экземпля ров классификатора в контексте структурированного классификато ра. Каждая часть может иметь: • имя роли – описательное имя роли, исполняемой экземплярами в контексте структурированного классификатора; • тип – только экземпляры этого типа (или подтипа этого типа) могут играть эту роль; • кратность – число экземпляров, которые могут играть роль в любой конкретный момент времени. Соединители – это отношения между ролями (частями). Соединители и части существуют только в рамках контекста конкретного структури рованного классификатора. Соединитель (connector) – это отношение между частями в контексте структурированного классификатора. Он указывает на то, что части могут общаться друг с другом и что между экземплярами, играющими роль частей, через которые это общение может происходить, сущест вует отношение. Эти отношения могут проецироваться в ассоциации между классами частей. Или они могут быть просто специальными от 410 Глава 18. Уточнение отношений, выявленных при анализе ношениями, при которых структурированный классификатор объеди няет части во временную кооперацию для осуществления некоторой задачи. Синтаксис структурированного классификатора показан на рис. 18.19 на примере класса SomeClass (некоторый класс). Основные моменты синтаксиса структурированного классификатора: • части кооперируются в контексте структурированного классифика тора; • части представляют роли, которые могут играть экземпляры клас сификатора в контексте структурированного классификатора – части не представляют классы; • соединитель – это отношение между двумя частями, которое ука зывает на то, что экземпляры, играющие роли, определенные час тями, могут общаться некоторым образом. Из этого списка видно, что при моделировании структурированного классификатора учитываются только внутренняя реализация и внеш ний интерфейс одного классификатора. Все классификаторы, не яв ляющиеся частями структурированного классификатора, игнориру ются. Таким образом, это очень узкоспециализированная техника мо делирования. 18.12.2. Структурированные классы Структурированный класс имеет дополнительное ограничение: он вла деет всеми своими частями, соединителями и портами (см. раздел 19.6). Между ними и классом устанавливается неявное отношение включе ния. Давайте рассмотрим пример использования структурированных клас сов на практике. На рис. 18.20 показана диаграмма классов для прос SomeClass part1:T ype1[0..2] part2:T ype2[*] StructuredClassSyntax части структурированный класс диаграмма классов имя роли тип кратность * 1 соединитель Рис. 18.19. Синтаксис структурированного классификатора |