области. Однако он весьма приблизителен и непригоден для сколько-нибудь сложных проблем. Человеческий язык - ужасно неточное средство выражения, потому список объектов и операций зависит от умения разработчика записывать свои мысли. Тем более, что для многих существительных можно найти соответствующую глагольную форму и наоборот.
Структурный анализ. Вторая альтернатива классической технике объектно- ориентированного анализа использует структурный анализ как основу для объектно-ориентированного проектирования. Такой подход привлекателен потому, что много аналитиков применяют этот подход и имеется большое число программных CASE-средств, поддерживающих автоматизацию этих методов. Нам лично не нравится использовать структурный анализ как основу для объектно-ориентированного проектирования, но для некоторых организаций такой прагматический подход не имеет альтернативы.
После проведения структурного анализа мы уже имеем модель системы, описанную диаграммами потоков данных и другими продуктами структурного анализа. Эти диаграммы дают нам формальную модель проблемы. Исходя из модели, мы можем приступить к определению осмысленных классов и объектов тремя различными способами.
МакМенамин и Палмер предлагают сначала приступить к формированию словаря данных и затем к анализу контекстных диаграмм модели. Они говорят:
'рассматривая список основных структур данных, следует подумать, о чем они говорят или что описывают. Например, если они прилагательные, то какие существительные они описывают? Ответы на такие вопросы могут пополнить ваш список объектов' [47]. Эти кандидаты в объекты происходят из окружающей среды, из существенных входных и выходных данных, а также продуктов, услуг и других ресурсов, которыми она управляет.
Следующие два способа основаны на анализе отдельных диаграмм потоков данных. Если взять какую- нибудь диаграмму потоков (в терминологии Барда и Меллора [48]), то кандидаты в объекты это:
• внешние сущности;
• хранилища данных;
• хранилища управляющих сущностей;
• управляющие преобразования.
Кандидаты в классы:
• потоки данных;
• потоки управления.
Остается преобразование данных, которое мы можем рассматривать как операции над существующими объектами или как поведение некоторого объекта, который мы создали специально для выполнения нужного преобразования.
Зайдевиц и Старк предлагают еще один метод, который они называют анализом абстракций. Метод базируется на идентификации основных сущностей, которые по своей природе аналогичны основным преобразованиям в структурном проектировании. Как они говорят, 'в структурном анализе входные и выходные данные изучаются до тех пор, пока не достигнут высшего уровня абстракции. Процесс преобразования входных данных в выходные есть основное преобразование. В абстрактном анализе разработчик делает то же самое, а также изучает основное преобразование для того, чтобы определить, какие процессы и состояния представляют наилучшую абстрактную модель системы' [49]. После определения основной сущности в диаграмме потоков данных аналитик приступает к изучению всей инфраструктуры, прослеживая входящие и исходящие потоки данных из центра, группируя процессы и состояния, встречающиеся по пути. Для практического использования авторы нашли анализ абстракций слишком сложным и в качестве альтернативы предлагают объектно- ориентированный анализ [50].
Необходимо отметить, что принципы структурного проектирования, которое, естественно, следует за структурным анализом, полностью ортогональны принципам объектно-ориентированного проектирования. Наш опыт показывает, что использование структурного анализа в процессе объектно-ориентированного проектирования часто приводит к полному провалу, если разработчик не способен сопротивляться желанию свалиться в структурную пропасть. Другая очень серьезная опасность заключается в том, что многие аналитики любят рисовать диаграммы потоков данных, которые представляют собой скорее описание проекта, чем модель существа системы. Очень трудно построить объектно-ориентированную систему, если модель столь очевидно ориентирована на алгоритмическую декомпозицию. Поэтому мы предпочитаем объектно-ориентированный анализ и анализ проблемной области как подготовительный этап для объектно-ориентированного проектирования. При этом уменьшается риск замусорить проект элементами алгоритмического анализа.
Если же по каким-либо уважительным причинам [Политические и исторические причины в качестве уважительных не принимаются] приходится взять за основу структурный анализ, прекратите строить диаграммы, как только они начинают смахивать на проект программы, а не на модель предметной области. Помните, что материалы проектирования, такие, как диаграммы потоков данных, это не конечный продукт, а инструмент разработчиков. Обычно строятся диаграммы, а затем разрабатываются механизмы, обеспечивающие необходимое поведение системы, то есть сам акт проектирования видоизменяет начальную модель. Поддержание соответствия модели и развивающегося проекта - дело трудное, и, честно говоря, бесполезное. Имеет смысл сохранять только продукт структурного анализа высокого уровня абстракции. Он отражает существенные черты и достаточно независим от проекта системы.
4.3. Ключевые абстракции и механизмы
Ключевые абстракции
Поиск и выбор ключевых абстракций. Ключевая абстракция - это класс или объект, который входит в словарь проблемной области. Самая главная ценность ключевых абстракций заключена в том, что они определяют границы нашей проблемы: выделяют то, что входит в нашу систему и поэтому важно для нас, и устраняют лишнее. Задача выделения таких абстракций специфична для проблемной области. Как утверждает Голдберг, 'правильный выбор объектов зависит от назначения приложения и степени детальности обрабатываемой информации' [51].
Как мы уже отмечали, определение ключевых абстракций включает в себя два процесса: открытие и изобретение. Мы открываем абстракции, слушая специалистов по предметной области: если эксперт про нее говорит, то эта абстракция обычно действительно важна [52]. Изобретая, мы создаем новые классы и объекты, не обязательно являющиеся частью предметной области, но полезные при проектировании или реализации системы. Например, пользователь банкомата говорит 'счет, снять, положить'; эти термины - часть словаря предметной области. Разработчик системы использует их, но добавляет свои, такие, как база данных, диспетчер экрана, список, очередь и так далее. Эти ключевые абстракции созданы уже не предметной областью, а проектированием.
Наиболее мощный способ выделения ключевых абстракций - сводить задачу к уже известным классам и объектам. Как будет показано ниже в главе 6, при отсутствии таких повторно используемых абстракций мы рекомендуем пользоваться сценариями, чтобы вести процесс идентификации классов и объектов.
Уточнение ключевых абстракций. Определив кандидатов на роли ключевых абстракций, мы должны оценить их по критериям, описанным в предыдущих главах. По словам Страуструпа 'программист должен задаваться вопросами: Как создаются объекты класса? Как можно копировать и/или уничтожать объекты данного класса? Какие операции могут быть выполнены над этим объектом? Если ответы на эти вопросы туманны, то, возможно, общая концепция не ясна и лучше сесть и подумать еще раз, чем бросаться программировать' [53].
Определив новые абстракции, мы должны найти их место в контексте уже существующих классов и объектов. Не стоит пытаться делать это строго сверху вниз или снизу вверх. Халберт и О'Брайен утверждают, что 'нет особой необходимости строить иерархию классов, начиная с самого верхнего класса,