совокупности эти диаграммы предоставляют возможность проследить их появление непосредственно из начальных требований к системе. Диаграммы процессов соответствуют программам, которые являются корневыми модулями диаграммы модулей. Каждый модуль представляет реализацию некоторой комбинации классов и объектов, которые, в свою очередь, можно найти на диаграммах классов и объектов соответственно. Наконец, диаграммы объектов представляют сценарии, определяемые требованиями, а диаграммы классов демонстрируют ключевые абстракции, которые формируют словарь предметной области.
Содержание документации
Документация по архитектуре системы важна, но ее составление не должно быть двигателем процесса разработки: документация - существенный, но не самый главный результат. Важно помнить, что документация - живой продукт, и ей надо позволить эволюционировать вместе с релизами проекта. Вместе с текстом программ сопровождающая документация служит основой для проведения многих формальных и неформальных просмотров.
Что должно быть документировано? Очевидно, что документация, представляемая конечному пользователю, должна включать инструкции по установке и использованию каждого релиза. Кроме того, должны быть документированы результаты анализа, чтобы зафиксировать семантику функциональных точек системы в последовательности сценариев. Должна также вестись документация по архитектуре и реализации для согласования в команде разработчиков общего видения системы и деталей архитектуры, а также для того, чтобы сохранить информацию обо всех стратегических решениях - это несомненно облегчает эволюцию и адаптацию системы.
Документация по архитектуре и реализации должна описывать:
• архитектуру системы верхнего уровня;
• ключевые абстракции и механизмы архитектуры;
• сценарии, иллюстрирующие важнейшие аспекты предусмотренного поведения системы.
Наихудшая документация, которую можно создать для объектно-ориентированной системы - это расписанные по классам объяснения смысла каждого метода в отдельности. При таком подходе получаются горы бесполезной бумаги, которую никто не читает и не доверяет ей, причем оказываются потеряны наиболее важные архитектурные решения, выходящие за рамки отдельных классов и проявляющиеся в сотрудничестве классов и объектов. Гораздо лучше документировать эти структуры верхнего уровня на языке диаграмм в описанной выше системе обозначений, но без явных операторов языка программирования, и сделать ссылки для разработчиков на интерфейсы важнейших классов для уточнения тактических деталей.
7.7. Инструменты
В предыдущих поколениях языков программирования команде разработчиков достаточно было иметь минимальный набор инструментов: редактор, компилятор, компоновщик и загрузчик - вот все, что обычно требовалось (и, чаще всего, все, что имелось). Особо благополучная команда могла обзавестись кодовым отладчиком. Сложные задачи в корне изменили картину: попытка построить большую программную систему с минимальным набором инструментов эквивалентна намерению возвести многоэтажное здание вручную.
Объектно-ориентированный подход также изменил многое. Традиционные инструменты разработки сосредоточены только на тексте программы, но объектно-ориентированные анализ и проектирование выдвигают на первый план ключевые абстракции и механизмы, и нам нужны инструменты, работающие с более богатой семантикой. Кроме того, для ускорения движимого макропроцессом объектно- ориентированного развития, требуются инструменты, позволяющие ускорить циклы разработки, особенно цикл редактирование/компиляция/выполнение/отладка.
Важно выбрать хорошо масштабируемые инструменты. Инструмент, который удобен для программиста- одиночки, занятого написанием небольшого приложения, не всегда подходит для производства сложных систем. На самом деле, для каждого инструмента существует порог, за которым его возможности оказываются превышены: его достоинства перевешиваются неуклюжестью и нерасторопностью.
Виды инструментов
Мы выделяем по крайней мере семь различных видов инструментов для объектно-ориентированной разработки. Первый инструмент - система с графическим интерфейсом, поддерживающая объектно- ориентированную систему обозначений, представленную в главе 5. Такой инструмент может быть использован при анализе, чтобы зафиксировать семантику сценариев, на ранних стадиях разработки, чтобы передать стратегические и тактические решения, принятые при проектировании, а также для координирования действий проектировщиков. Подобный инструмент будет полезен на протяжении всего жизненного цикла и при сопровождении системы. В частности, мы считаем возможным восстанавливать по тексту программы многие важные аспекты объектно-ориентированной системы. Такая способность инструментальной системы очень важна: в традиционных CASE-средствах разработчик может создавать замечательные картинки только для того, чтобы обнаружить, что они устарели, потому что программисты манипулируют реализацией, не отраженной в проекте. Восстановление проекта по коду снижает вероятность того, что документация будет идти не в ногу с реализацией.
Следующий важный для объектно-ориентированной разработки инструмент - броузер, который показывает структуру классов и архитектуру модулей системы. Иерархия классов может сделаться настолько сложной, что трудно даже отыскать все абстракции, которые были введены при проектировании или выявить кандидатов для повторного использования [16]. При изучении фрагмента программы разработчику может понадобиться посмотреть определение класса некоторого объекта. Найдя этот класс, ему вероятно придется заглянуть в описание какого-нибудь из его суперклассов. Рассматривая этот суперкласс, разработчик может захотеть внести изменения в интерфейс класса, но при этом придется изучить поведение всех его клиентов. Этот анализ будет особенно громоздким, если он применяется к файлам, которые представляют физические, а не логические аспекты проекта. По этой причине броузер оказывается очень важным инструментом объектно-ориентированного анализа и проектирования. Броузеры есть, например, в среде Smalltalk. Подобные средства, хотя и разного качества, имеются и для других объектно-ориентированных языков.
Другой вид инструментов, который очень важен, если не абсолютно необходим - инкрементный компилятор. Метод эволюционной разработки, который применяется в объектно-ориентированном программировании, нуждается в компиляторе, который мог бы компилировать отдельные объявления и операторы. Мейровиц замечает, что 'UNIX, с ее ориентацией на пакетное компилирование больших программных файлов в библиотеки, которые потом компонуются с другими фрагментами кода, не предоставляет необходимой поддержки для объектно-ориентированного программирования. Совершенно недопустимо тратить десять минут на компиляцию и компоновку, чтобы изменить реализацию метода и тратить целый час на компиляцию и компоновку только для того, чтобы добавить новое поле в суперкласс верхнего уровня! Для быстрой отладки методы и определения полей должны компилироваться инкрементно' [17]. Такие компиляторы существуют для многих языков, описанных в приложении. К сожалению, большинство реализации содержит традиционные пакетно-ориентированные компиляторы.
Мы также полагаем, что нетривиальные проекты нуждаются в отладчиках, которые могут работать с семантикой классов и объектов. При отладке программ часто требуется справка о переменных экземпляра и переменных класса для данного объекта. Традиционные отладчики для необъектных языков ничего не знают о классах и объектах. Так, пытаясь использовать стандартный отладчик языка С для программы на C++, разработчик не сможет получить всею информацию, необходимую для отладки объектно- ориентированной программы. Ситуация особенно критична для объектно-ориентированных языков, поддерживающих несколько потоков управления. При выполнении такой программы в один и тот же момент времени могут быть запущены несколько активных процессов. Естественно требуется отладчик, который позволял бы контролировать каждый отдельный поток и взаимодействие объектов между потоками.