Дж. Рамбо, М. Блаха - UML 2.0 - Объектно-ориентированное моделирование и разработка (1158633), страница 77
Текст из файла (страница 77)
требуемые свойстве П П Интервал А у рв урвет Рис. 15.1. Пропасть между ресурсами и требованиями 15.2. Наведение мостов 325 Если вы можете сконструировать нужные функции непосредственно из имеющихся ресурсов, задача решена. Например, комиссионер может рассчитать свои комиссионные при помощи электронной таблицы, исходя из различных предположений. В этой задаче имеющиеся ресурсы полностью соответствуют потребностям. Однако чаще всего задача решается не так просто. Предположим, вы хотите создать интернет-каталог с возможностью заказа товаров. В этом случае вы не сможете сразу же создать систему из электронной таблицы или написать ее на языке программирования, так как пропасть между ресурсами и потребностями слишком велика.
Вам придется придумывать какие-то промежуточные элементы, так чтобы каждый элемент выражался через несколько элементов более низкого уровня (рис. 15.2). Более того, если пропасть слишком велика, промежуточные элементы также придется разделить на несколько уровней. Эти элементы могут быть операциями, классами или иными конструкциями ОМ1.. Изобретение подходящих промежуточных элементов и составляет самую суть успешного проектирования. Трвоувмыв свойстве Свнзуюн4не злементы Достуоныв ресурсы Рис.
1$.2. Наведение мостов Чаще всего промежуточные элементы не выделяются из условия задачи очевидным образом. Может существовать множество способов реализовать высокоуровневую операцию. Вам придется угадать возможный набор промежуточных операций, а затем попытаться реализовать их. Будьте аккуратны с промежуточными операциями, которые похожи друг на друга, но не являются идентичными. Вы можете сократить объем кода и сделать его более ясным, объединив похожие операции в более универсальные.
Модифицированные операции могут не так хорошо подходить к некоторым высокоуровневым операциям, однако на этот компромисс приходится идти, так как хорошее проектирование подразумевает оптимизацию системы в целом, а не отдельных ее частей. Если промежуточные элементы уже были построены раньше, вы можете просто воспользоваться ими, но принцип наведения мостов остается тем же самым.
Вам все равно придется искать нужные элементы в каркасе или библиотеке классов и подгонять их друг к другу. Проблема не в том, чтобы создавать отдельные элементы — с этим справится кто угодно. Проблема в том, чтобы надежно соединить между собой эти части н получить из них цельную систему. Проектирование особенно сложно, потому что это не аналитическая задача. Невозможно вывести идеальную систему, просто изучив системные требования. Комбинаций промежуточных элементов может быть слишком много, чтобы перебрать их все.
Поэтому необходимо применять эвристические методики. 326 Глава 15 ° Проектирование классов Проектирование требует синтеза: вы должны придумывать новые промежуточные элементы и соединять их друг с другом. Это творческая работа, подобная решению головоломок, доказательству теорем, игре в шахматы, строительству мостов или написанию симфоний.
Никто не сделает для вас кнопку, нажав которую вы сможете получить готовый проект. Результаты предшествуюших этапов процесса разработки помогут вам найти нужное направление, подобно учебникам шахматной игры, инженерным справочникам или лекциям по теории музыки, но в конечном итоге создание проекта требует совершения определенного творческого акта.
15.3. Реализация вариантов использования В главе 13 мы добавили в модель классов основные операции. Теперь мы должны разбить эти операции, происходящие главным образом из вариантов использования, на составные части. Варианты использования определяют требуемое поведение, но они не ограничивают его реализацию. Цель проектирования состоит в том, чтобы сделать выбор между возможными вариантами реализации и подготовить ее осуШествление. Каждый вариант обладает своими преимуществами и недостатками.
Недостаточно просто добиться выполнения необходимого поведения, хоть это и главная задача. Вы должны учесть влияние каждого принятого решения на производительность, надежность, легкость усовершенствования и другие параметры. Проектирование— это процесс реализации функциональности с учетом конфликтуюших между собой потребностей. Варианты использования определяют гюведение на уровне системы в целом.
В процессе проектирования вы должны изобретать новые операции и объекты, которые будут обеспечивать это поведение. Затем вы должны определить каждую из новых операций в терминах операций более низкого уровня, в которых задействовано большее количество объектов. В конце концов, вы сможете реализовать оставшиеся операции непосредственно в терминах существующих операций.
Изобретение промежуточных операций и есть то, что мы называем «наведением мостовм Начинать нужно с составления списка ответственности варианта использования или операции. Ответственностью называется нечто известное объекту или нечто такое, что он должен сделать [%'! гГз-Вгоск-90), Ответственность не является четко определенным понятием.
Это просто средство, помогающее мыслительному процессу. Например, в'театральной интернет-кассе процедура бронирования должна найти свободные места на выбранном спектакле, пометить их как занятые, получить платеж от покупателя, организовать доставку билетов и перевести платеж на соответствующий счет. Занятость мест должна отслеживать система самого театра, она же должна определять цену различных мест и т. д. Каждая операция может нести ответственность за несколько действий. Некоторые виды ответственности могут быть общими у разных операций. Группируйте виды ответственности в кластеры и старайтесь делать эти кластеры согласованными.
Это означает, что каждый кластер должен состоять из родственных видов ответственности, которые могут обслуживаться одной низкоуровневой операцией. В некоторых случаях, когда виды ответственности получаются достаточно широко ~5.3. Реализация вариантов использования 327 определенными и независимыми друг от друга, каждый из этих видов становится кластером сам по себе. После этого нужно определить операцию для каждого кластера видов ответственности. Операцию следует определять так, чтобы она не ограничивалась конкретными обстоятельствами. Следует избегать и чрезмерной общности определений, потому что тогда операция получается нечеткой. Цель состоит в том, чтобы предвидеть возможное использование новой операции в будущем. Если операция может быть использована в нескольких частях текущего проекта, достаточно будет сделать ее такой общей, чтобы она покрывала все существующие варианты своего применения.
Наконец, назначьте новые низкоуровневые операции классам. Если подходящих классов найти не удается, вам придется придумать и добавить в модель новый класс низкого уровня. Пример с банкоматом. Один из вариантов использования из главы 13 назывался Ргосеы Ггапзастюп (обработка транзакции). Вспомните, что Тгппысиоп (Транзакция) — это множество классов Урдаге (Обновление) и что логика операции зависит от того, является ли транзакция снятием денег со счета, помещением их на счет или переводом денег между счетами. ° Свяглие денег со счета (вчгЫга~ча1). Операция снятия денег несет ответственность за множество действий, таких как: получение суммы транзакции от клиента, проверка наличия достаточных средств на счете, проверка соответствия указанной суммы политике банка, проверка наличия достаточных средств в банкомате, выдача наличных, уменьшение суммы на счете, печать клиентского чека.
Некоторые из этих действий должны выполняться в контексте транзакции базы данных. Такая транзакция гарантирует, что либо все действия будут выполнены вместе, либо ни одно из них. Это относится, например, к выдаче наличных и уменьшению суммы на счете. ° Размещение денег яа счете (оероз1г). Операция размещения денег на счете несет ответственность за такие действия, как: получение суммы транзакции от клиента, получение конверта с деньгами от клиента, печать временной метки на конверте, увеличение счета, печать клиентского чека.
Некоторые действия также должны выполняться в контексте транзакции. ° Трансфер (ггапзгег). Операция несет ответственность за такие действия, как: получение номера исходного счета, получение номера целевого счета, получение суммы трансфера, проверка наличия достаточных средств на исходном счете, проверка соответствия указанной суммы политике банка, уменьшение суммы на исходном счете, увеличение суммы на целевом счете, печать суммы на чеке.
И здесь некоторые действия должны выполняться в контексте транзакции. Видно, что некоторые виды ответственности присутствуют в нескольких операциях. Например, все операции запрашивают у клиента сумму транзакции. Операции 1гапз/ег (трансфер) и жт)ц(гама! (снятие) проверяют наличие достаточных средств на счете. Правильный проект должен объединять это поведение и реализовывать его один раз. 328 Глава 15 ° Проектирование классов 15А. Проектирование алгоритмов На этом этапе нужно сформулировать алгоритм для каждой операции. Аналитическая спецификация описывает, что именно должна делать операция для своих клиентов, а алгоритм показывает, как это делается. Проектирование алгоритмов также делится на несколько этапов.