UML2 и унифицированный процесс. Джим арлоуайла нейштадтпрактический объектно ориентированныйанализ и проектированиеu
![]()
|
5.5. Отношение «extend» Отношение «extend» – способ введения нового поведения в существую щий прецедент. Прецедент: ChangeEmployeeDetails Второстепенные актеры: Нет. Предусловия: 1. Manager входит в систему. Постусловия: 1. Данные служащего изменены. Основной поток: 1. include (FindEmployeeDetails). 2. Система выводит данные служащего. 3. Manager меняет данные служащего. … ID: 1 Краткое описание: Manager меняет данные служащего. Альтернативные потоки: Нет. Прецедент: ViewEmployeeDetails Второстепенные актеры: Нет. Предусловия: 1. Manager входит в систему. Постусловия: 1. Система вывела на экран данные служащего. Основной поток: 1. include (FindEmployeeDetails). 2. Система выводит данные служащего. … ID: 2 Краткое описание: Manager просматривает данные служащего. Альтернативные потоки: Нет. Прецедент: DeleteEmployeeDetails Второстепенные актеры: Нет. Предусловия: 1. Manager входит в систему. Постусловия: 1. Данные служащего удалены. Основной поток: 1. include (FindEmployeeDetails). 2. Система выводит данные служащего. 3. Manager удаляет данные служащего. … ID: 3 Краткое описание: Manager удаляет данные служащего. Альтернативные потоки: Нет. Главные актеры: Manager Главные актеры: Manager Главные актеры: Manager Рис. 5.8. Семантика отношения «include» 128 Глава 5. Дополнительные аспекты моделирования прецедентов Отношение «extend» предоставляет возможность ввести новое поведе ние в существующий прецедент (рис. 5.10). Базовый прецедент пре доставляет набор точек расширения (extension points) – точек входа, в которые может быть добавлено новое поведение. А расширяющий прецедент предоставляет ряд сегментов вставки, которые можно ввести в базовый прецедент в места, указанные точками входа. Как вскоре бу дет показано, отношение «extend» может использоваться для того, чтобы точно указать, какие именно точки расширения базового прецедента подлежат расширению. В отношении «extend» любопытно то, что базовый прецедент ничего не знает о расширяющих прецедентах, он просто предоставляет для них точки входа. Базовый прецедент абсолютно полон и без расширений. Это существенно отличает «extend» от отношения «include», где базовые Issue fine Borrow book Librarian Return book Find book «exte nd» Cистема Library базовый прецедент расширяющий прецедент отношение расширения Рис. 5.10. Отношение «extend» Прецедент: FindEmployeeDetails Главные актеры: Manager Предусловия: 1. Manager входит в систему. Постусловия: 1. Система нашла данные служащего. Основной поток: 1. Manager вводит ID служащего. 2. Система ищет данные служащего. ID: 4 Краткое описание: Manager ищет данные служащего. Альтернативные потоки: Нет. Второстепенные актеры: Нет. Рис. 5.9. Пример неполного включаемого прецедента 5.5. Отношение «extend» 129 прецеденты остаются неполными без включаемых прецедентов. Более того, точки расширения на самом деле не вводятся в поток событий ба зового прецедента; они накладываются поверх потока. Точки расширения обозначаются в потоке событий базового прецеден та, как показано на рис. 5.11. Точки расширения также можно пока зать на диаграмме прецедентов, перечислив их в новой ячейке пикто граммы базового прецедента. Обратите внимание на то, что точки расширения в основном потоке не пронумерованы. Они появляются между пронумерованными шагами потока. UML явно определяет тот факт, что точки расширения факти чески существуют в слое поверх основного потока. Следовательно, они вообще не являются его частью. Этот слой подобен прозрачной пленке, наложенной поверх основного потока, на которую нанесены точки рас ширения. Основная идея введения этого слоя – сделать поток базового прецедента полностью независимым от точек расширения. Иначе го воря, поток базового прецедента не знает (или не интересуется), в ка ких точках происходит его расширение. Это позволяет использовать отношение «extend» для создания произвольных или специальных рас ширений потока базового прецедента. При использовании «extend» базовый прецедент выступает в роли мо дульного каркаса, к которому можно подключать расширения в пред определенных точках расширения. В примере на рис. 5.11 в базовом Прецедент: ReturnBook Второстепенные актеры: Нет. Предусловия: 1. Librarian входит в систему. Постусловия: 1. Книга возвращена. Основной поток: 1. Librarian вводит ID читателя. 2. Система выводит данные читателя, включая список взятых им книг. 3. Librarian находит возвращаемую книгу в списке книг. точка расширения: overdueBook 4. Librarian возвращает книгу. … ID: 9 Краткое описание: Librarian возвращает взятую книгу. Альтернативные потоки: Нет. IssueFine точка расширения базовый прецедент расширяющий прецедент extension point: overdueBook имя точки расширения Главные актеры: Librarian «extend» extension points overdueBook ReturnBook Рис. 5.11. Обозначение точек расширения 130 Глава 5. Дополнительные аспекты моделирования прецедентов прецеденте ReturnBook точка расширения overdueBook находится между шагами 3 и 4 потока событий. Отношение «extend» предоставляет хороший способ обработки исклю чительных ситуаций или ситуаций, когда нужен гибкий каркас, по скольку невозможно предсказать (или просто не известны) все воз можные расширения. 5.5.1. Расширяющий прецедент Расширяющие прецеденты обычно не являются полными прецедента ми, поэтому, как правило, их экземпляр не может быть создан. Обыч но они состоят всего из одного или нескольких фрагментов поведения, называемых сегментами вставки. Отношение «extend» определяет точ ку расширения в базовом прецеденте, в которой будет введен сегмент вставки. Здесь действуют следующие правила: • Отношение «extend» должно определять одну или несколько точек расширения базового прецедента. В противном случае предполага ется, что отношение «extend» относится ко всем точкам расширения. • В расширяющем прецеденте должно быть столько же сегментов вставки, сколько точек расширения определено в отношении «extend». • Два расширяющих прецедента могут «расширять» один базовый прецедент в одной и той же точке расширения. Но в этом случае по рядок выполнения расширений не определен. В примере на рис. 5.12 в расширяющем прецеденте всего один сегмент вставки IssueFine (назначить штраф). Расширяющий прецедент может также иметь предусловия и постусло вия. Предусловия должны быть выполнены, в противном случае сег Расширяющий прецедент: IssueFine Главные актеры: Librarian Сегмент 1 предусловия: 1. Возвращенная книга просрочена. Сегмент 1 постусловия: 1. Штраф записан в системе. 2. Система распечатала штраф. Поток сегмента 1: 1. Librarian вводит данные штрафа в систему. 2. Система распечатывает штраф. ID: 10 Краткое описание: Сегмент 1: Librarian записывает и распечатывает штраф. ReturnBook extension points overdueBook IssueFine extension point: overdueBook единственная вставка расширяющего прецедента IssueFine вводится в точке вставки overdueBook прецедента ReturnBook Второстепенные актеры: Нет. «extend» Рис. 5.12. Расширяющий прецедент с одним сегментом вставки 5.5. Отношение «extend» 131 мент не выполняется. Постусловия ограничивают состояние системы после выполнения сегмента. У самих расширяющих прецедентов могут быть расширяющие или включаемые прецеденты. Однако лучше избегать такой вложенности, поскольку это сильно усложняет систему. 5.5.2. Несколько сегментов вставки В расширяющем прецеденте может быть несколько сегментов встав ки. Это полезно в тех случаях, когда не получается полностью реали зовать расширение в одном сегменте из за того, что необходимо вер нуться и что то сделать в основном потоке базового прецедента. Обра тимся к примеру, изображенному на рис. 5.13. Пусть после записи и распечатки штрафа выполнение возвращается в основной поток для обработки других просроченных книг, после чего в точке расширения payFine (выплатить штраф) должнику предлагается заплатить общую сумму штрафа. Конечно, такая процедура более эффективна, чем взи мание платежей по каждому штрафу в отдельности (так произошло бы, если бы эти два сегмента были сведены в один сегмент IssueFine). При создании расширяющих прецедентов с несколькими сегментами необходимо четко нумеровать каждый сегмент, как показано на рис. 5.13, поскольку здесь важен порядок сегментов: первый сегмент Расширяющий прецедент: IssueFine Второстепенные актеры: Нет. Сегмент 1 предусловия: 1. Возвращенная книга просрочена. Сегмент 1 постусловия: 1. Штраф записан в системе. 2. Система распечатала штраф. Поток сегмента 1: 1. Librarian вводит данные штрафа в систему. 2. Система распечатывает штраф. ID: 10 Краткое описание: Сегмент 1: Librarian записывает и распечатывает штраф. Сегмент 2: Librarian принимает платеж по штрафу. ReturnBook extension points overdueBook payFine IssueFine extension points: overdueBook, payFine первый сегмент расширяющего прецедента IssueFine вводится в точке расширения overdueBook, а второй сегмент – в точке payFine Сегмент 2 предусловия: 1. Штраф взыскан с должника. Сегмент 2 постусловия: 1. Штраф зарегистрирован как выплаченный. 2. Система распечатала квитанцию об уплате штрафа. Поток сегмента 2: 1. Librarian принимает платеж по штрафу от должника. 2. Librarian вводит выплаченный штраф в систему. 3. Librarian распечатывает квитанцию об уплате штрафа. Главные актеры: Librarian «extend» Рис. 5.13. Расширяющий прецедент с двумя сегментами вставки 132 Глава 5. Дополнительные аспекты моделирования прецедентов вставляется в первой точке расширения и т. д. Поэтому надо очень ак куратно записывать сегменты в правильном порядке, а затем придер живаться его. 5.5.3. Условные расширения Пример на рис. 5.14 демонстрирует другой, более гуманный подход к должнику: если он впервые задержал книгу, выдается предупрежде ние, а штраф выписывается только при повторном нарушении правил. Это можно смоделировать путем добавления нового расширяющего прецедента IssueWarning (выдать предупреждение) и введения условий в отношения «extend». Условия (conditions) – это логические выраже ния. Вставка осуществляется только в том случае, если выражение истинно. Обратите внимание, что расширяющий прецедент IssueWarning вводит ся только в точке расширения overdueBook (просроченная книга). Одна ко (как и ранее) расширяющий прецедент IssueFine вводится и в точке ReturnBook extension points overdueBook payFine condition: {первое нарушение} extension points: overdueBook IssueWarning условие condition: {!первое нарушение} extension points: overdueBook, payFine IssueFine «extend» «extend» Рис. 5.14. Добавление условного расширяющего прецедента Расширяющий прецедент: IssueWarning Второстепенные актеры: Нет. Сегмент 1 предусловия: 1. Возвращенная книга просрочена. Сегмент 1 постусловия: 1. Предупреждение записано в системе. Поток сегмента 1: 1. Librarian вводит данные предупреждения в систему. ID: 11 Краткое описание: Сегмент 1: Librarian выдает предупреждение. Главные актеры: Librarian Рис. 5.15. Описание условного расширяющего прецедента 5.6. Когда применять дополнительные возможности 133 overdueBook, и в точке payFine (выплатить штраф). Это свидетельствует о том, что IssueWarning (рис. 5.15) содержит только один сегмент встав ки, тогда как IssueFine (как мы уже видели) – два. 5.6. Когда применять дополнительные возможности Применяйте дополнительные возможности, только если они упрощают модель и делают ее более понятной. Применяйте дополнительные возможности, только если они упроща ют модель прецедентов. Мы вновь убеждаемся в том, что лучшие моде ли прецедентов – это простые модели. Запомните, что модель преце дентов – это изложение требований, то есть она должна быть понятной не только разработчикам моделей, но и заинтересованным сторонам. Простая модель прецедентов, в которой дополнительные возможности применяются редко или вообще отсутствуют, предпочтительнее моде ли, переполненной дополнительными возможностями, даже если по следняя кажется разработчику более изысканной. Учитывая опыт моделирования прецедентов в различных компаниях, можно сделать следующие выводы: • обычно заинтересованные стороны после небольшой тренировки и обучения могут без труда разбираться в актерах и прецедентах; • заинтересованным сторонам сложнее воспринимать обобщение ак теров; • широкое использование отношения «include» затрудняет понимание моделей прецедентов – заинтересованным сторонам и разработчи кам моделей приходится рассматривать несколько прецедентов для получения полной картины; • у заинтересованных сторон возникают большие сложности с пони манием отношения «extend» даже после подробных объяснений; • как это ни удивительно, многие разработчики объектных моделей неверно понимают семантику отношения «extend»; • обобщение прецедентов следует применять, только если в системе используются абстрактные (а не конкретные) родительские преце денты, в противном случае это сильно усложняет дочерние преце денты. 5.7. Советы и рекомендации по написанию прецедентов В данном разделе предлагается несколько советов и рекомендаций по написанию прецедентов. 134 Глава 5. Дополнительные аспекты моделирования прецедентов 5.7.1. Делайте прецеденты короткими и простыми Основной девиз: «Делайте прецеденты короткими, делайте их просты ми». Они должны включать именно такой объем информации, которо го достаточно для записи требований. К сожалению, в некоторых про ектах разработчики избегают простого и сжатого изложения и стре мятся к непомерному увеличению объема документации. Гради Буч называет эту тенденцию «бумажной жадностью». Есть хорошее правило: основной поток прецедента должен помещать ся на одной странице. Немного больше, и прецедент практически на верняка окажется слишком длинным. В реальности большинство пре цедентов короче половины страницы. Начать надо с упрощения фраз (использовать только короткие повест вовательные предложения, как описано в разделе 3.6.2). Затем уда лить все детали проектирования (см. следующий раздел). Если преце дент по прежнему слишком велик, необходимо повторно проанализи ровать проблему. Вероятно, прецедент можно разбить на несколько прецедентов либо выделить альтернативные потоки. 5.7.2. Фокусируйтесь на том «что», а не «как» Помните, прецеденты создаются для того, чтобы понять, чего актеры ждут от системы, а не как она должна это осуществлять. «Как» стано вится ясно позже, при проектировании. Смешение «что» с «как» явля ется повсеместной проблемой. Разработчик, работая над прецедентом, придумывает какое то решение. Рассмотрим, к примеру, следующий фрагмент прецедента: 4. Система просит Покупателя подтвердить заказ. 5. Покупатель нажимает кнопку OK. В данном примере разработчик прецедента представил себе некий пользовательский интерфейс: форму с кнопкой «ОК». Из за этого пре цедент перестал быть простым изложением требований, это первич ный проект. Лучше записать шаг 5 следующим образом: 5. Покупатель соглашается с заказом. Детали проектирования (которые пока неизвестны!) должны оставать ся вне прецедента. 5.7.3. Избегайте функциональной декомпозиции Функциональная декомпозиция не подходит для моделей прецедентов. 5.7. Советы и рекомендации по написанию прецедентов 135 При анализе прецедентов широко встречается следующая ошибка: создается ряд «высокоуровневых» прецедентов, которые затем разби ваются на ряд прецедентов более низкого уровня и т. д. до «элементар ных» прецедентов, достаточно детализированных для реализации. Та кой подход к разработке программного обеспечения называется функ циональной декомпозицией. Он абсолютно ошибочен в применении к моделированию прецедентов. Рассмотрим пример. На рис. 5.16 аналитик описал работу библиотеч ной системы с помощью одного высокоуровневого прецедента RunLibra ry (управление библиотекой). Затем путем функциональной декомпо зиции разложил его на все более и более детализированные уровни. Многим не ОО аналитикам рис. 5.16 кажется вполне приемлемым. Однако с точки зрения моделирования прецедентов в предложенном примере содержится много ошибок: • Модель сосредоточена не на фиксировании требований, а на искус ственном структурировании этих требований – существует множе ство возможных вариантов декомпозиции. • Модель описывает систему как набор вложенных функций. Однако ОО системы в действительности являются наборами взаимодейст вующих объектов, обменивающихся сообщениями. Здесь очевид ное концептуальное несоответствие. LibrarySystem Librarian AddBook DeleteBook AddTicket DeleteTicket LendBook ReturnBook Избегайте функциональной декомпозиции «include» «include» «include» «include» «include» «include» «include» MaintainBooks MaintainTickets MaintainLoans «include» RunLibrary «include» Рис. 5.16. Пример функциональной декомпозиции 136 Глава 5. Дополнительные аспекты моделирования прецедентов • Интерес представляют только описания прецедентов самого низко го уровня: AddBook (добавить книгу), DeleteBook (удалить книгу), Add Ticket (добавить формуляр), DeleteTicket (удалить формуляр), LendBook (выдать книгу) и ReturnBook (вернуть книгу). Более высокие уровни просто вызывают нижние и ничего не привносят в модель с точки зрения отражения требований. |