|
Цель программирования - создать продукт, удовлетворяющий пользователя.
Важнейшим средством для достижении этой цели является создание
программы с ясной внутренней структурой и воспитание коллектива
программистов и разработчиков, имеющих достаточный опыт и мотивацию,
чтобы быстро и эффективно реагировать на все изменения.
Почему это так? Ведь внутрення структура программы и процесс, с
помощью которого она получена, в идеале никак не касаются конечного
пользователя. Более того, если конечный пользователь почему-то
интересуется тем, как написана программа, то что-то с этой программой
не так. Почему, несмотря на это, так важны структура программы и люди,
ее создавшие? В конце концов конечный пользователь ничего об этом
не должен знать.
Ясная внутренняя структура программы облегчает:
Главное здесь в том, что любая удачная большая программа имеет
долгую жизнь, в течение которой над ней работают
поколения программистов и разработчиков, она переносится на новую
машину, приспосабливается к непредусмотренным требованиям и несколько
раз перестраивается. Во все время жизни необходимо в приемлемое время и
с допустимым числом ошибок выдавать версии программы. Не планировать все
это - все равно, что запланировать неудачу.
Отметим, что, хотя в идеальном случае случае пользователи не
должны знать внутреннюю структуру системы, на практике они обычно
хотят ее знать. Например, пользователь может желать познакомиться в
деталях с разработкой системы с целью научиться контролировать
возможности и надежность системы на случай переделок и расширений.
Если рассматриваемый программный продукт есть не полная система, а набор
библиотек для получения программных систем, то пользователь захочет
узнать побольше "деталей", чтобы они служили источником идей и
помогали лучше использовать библиотеку.
Нужно уметь очень точно определить объем проектирования программы.
Недостаточный объем приводит к бесконечному срезанию острых углов
("побыстрее передадим систему, а ошибку устраним в следующей версии").
Избыточный объем приводит к усложненному описанию системы, в котором
существенное теряется в формальностях, в результате чего при
реорганизации программы получение работающей версии затягивается ("новая
структура намного лучше старой, пользователь согласен ждать ради нее").
К тому же возникают такие потребности в ресурсах, которые непозволительны
для большинства потенциальных пользователей. Выбор объема
проектирования - самый трудный момент в разработке, именно здесь
проявляется талант и опыт. Выбор трудно сделать и для одного программиста
или разработчика, но он еще труднее для больших задач, где занято
много людей разного уровня квалификации.
Организация должна создавать программный продукт и сопровождать
его, несмотря на изменения в штате, в направлении работы или в
управляющей структуре. Распространенный способ решения этих проблем
заключался в попытке сведения процесса создания системы к нескольким
относительно простым задачам, укладывающимся в жесткую структуру.
Например, создать группу легко обучаемых (дешевых) и взаимозаменяемых
программистов низкого уровня ("кодировщиков") и группу не таких
дешевых, но взаимозаменяемых (а значит также не уникальных)
разработчиков. Считается, что кодировщики не принимают решений по
проектированию, а разработчики не утруждают себя "грязными"
подробностями кодирования. Обычно такой подход приводит к неудаче, а
где он срабатывает, получается слишком громоздкая система с плохими
характеристиками.
Недостатки такого подхода состоят в следующем:
По сути, подобные системы - это бесполезная трата редких человеческих
талантов. Создание структуры, в рамках которой люди могут найти
применение разным талантам, овладеть новым родом деятельности и
участвовать в творческой работе - это не только благородное дело, но
и практичное, коммерчески выгодное предприятие.
С другой стороны, нельзя создать систему, представить документацию
по ней и бесконечно ее сопровождать без некоторой жесткой организационной
структуры. Для чисто новаторского проекта хорошо начать с того, что
просто найти лучших специалистов и позволить им решать задачу в
соответствии с их идеями. Но по мере развития проекта требуется все
больше планирования, специализации и строго определенного взаимодействия
между занятыми в нем людьми. Под строго определенным понимается не
математическая или автоматически верифицируемая запись (хотя это
безусловно хорошо там, где возможно и применимо), а скорее набор
указаний по записи, именованию, документации, тестированию и т.п.
Но и здесь необходимо чувство меры. Слишком жесткая структура может
мешать росту и затруднять совершенствование. Здесь подвергается
проверке талант и опыт менеджера. Для отдельного работника аналогичная
проблема сводится к определению, где нужно проявить смекалку, а где
действовать по рецептам.
Можно рекомендовать планировать не на период до выдачи следующей
версии системы, а на более долгий срок. Строить планы только до
выпуска очередной версии - значит планировать неудачу. Нужно иметь
организацию и стратегию развития программного обеспечения, которые
нацелены на создание и поддержание многих версий разных систем, т.е.
нужно многократное планирование успеха.
Цель проектирования в выработке ясной и относительно простой
внутренней структуры программы, называемой иногда архитектурой, иными
словами каркаса, в который укладываются отдельные программные фрагменты,
и который помогает написанию этих фрагментов.
Проект - конечный результат процесса проектирования (если только
бывает конечный продукт у итеративного процесса). Он является
средоточием взаимодействий между разработчиком и программистом и
между программистами. Здесь необходимо соблюсти чувство меры. Если я,
как отдельный программист, проектирую небольшую программу, которую
собираюсь написать завтра, то точность и полнота описания проекта
может свестись к нескольким каракулям на обратной стороне конверта.
На другом полюсе находится система, над которой работают сотни
программистов и разработчиков, и здесь могут потребоваться тома
тщательно составленных спецификаций проекта на формальном или
полуформальном языке. Определение нужной степени точности, детализации
и формальности проектирования является уже само по себе нетривиальной
технической и административной задачей.
Далее будет предполагаться, что проект системы записывается
как ряд определений классов (в которых частные описания опущены
как лишние детали) и взаимоотношений между ними. Это упрощение, т.к.
конкретный проект может учитывать: вопросы параллельности, использование
глобального пространства имен, использование глобальных функций и
данных, построение программы для минимизации перетрансляции,
устойчивость, многомашинный режим и т.п. Но при обсуждении на данном
уровне детализации без упрощения не обойтись, а классы в контексте С++
являются ключевым понятием проектирования. Некоторые из указанных
вопросов будут обсуждаться ниже, а те, которые прямо затрагивают
проектирование библиотек С++, будут рассмотрены в главе 13. Более
подробное обсуждение и примеры определенных методов объектно-
ориентированного проектирования содержатся в [2].
Мы сознательно не проводили четкого разделения анализа и
проектирования, поскольку обсуждение их различий выходит за рамки этой
книги, и оно зависит от применяемых методов проектирования. Главное в том,
чтобы выбрать метод анализа, подходящий для метода проектирования, и
выбрать метод проектирования, подходящий для стиля программирования
и используемого языка.