- •0. Введение: о курсе: версия для печати и pda
- •1.2 Парадигмы программирования
- •1.2.1 Процедурное программирование
- •1.2.5 Объектно-ориентированное программирование
- •1.5.1 Механизм вызова
- •1.5.3 Множественное наследование
- •1.6 Пределы совершенства
- •2. Лекция: Описания и константы: версия для печати и pda
- •2.2 Имена
- •2.3.2 Неявное преобразование типа
- •2.4 Литералы
- •2.4.4 Строки
- •2.6. Экономия памяти
- •2.6.1 Поля
- •3.1.1 Анализатор
- •3.1.2 Функция ввода
- •3.2 Сводка операций
- •3.2.3 Инкремент и декремент
- •3.2.5 Преобразование типа
- •3.2.6 Свободная память
- •3.3.2 Оператор goto
- •4.3.1 Единственный заголовочный файл
- •4.3.2 Множественные заголовочные файлы
- •4.4 Связывание с программами на других языках
- •5.3.1 Альтернативные реализации
- •5.3.2 Законченный пример класса
- •5.5.3 Свободная память
- •5.5.5 Массивы объектов класса
- •6. Лекция: Производные классы: версия для печати и pda
- •6.1 Введение и краткий обзор
- •6.2.3 Иерархия классов
- •6.2.4 Поля типа
- •6.4.1 Монитор экрана
- •6.5 Множественное наследование
- •7.3 Пользовательские операции преобразования типа
- •7.3.2 Операции преобразования
- •7.3.3 Неоднозначности
- •7.5 Большие объекты
- •Int size; // размер вектора, на который указывает p
- •7.13 Предостережения
- •7.14 Упражнения
- •8. Лекция: Шаблоны типа: версия для печати и pda
- •8.1 Введение
- •8.3.2 Список без принудительной связи
- •8.4.4 Неявная передача операций
- •8.4.5 Введение операций с помощью параметров шаблонного класса
- •8.7.1 Задание реализации с помощью параметров шаблона
- •9.1.2 Другие точки зрения на особые ситуации
- •9.3.2 Производные особые ситуации
- •9.4.2 Предостережения
- •9.4.3 Исчерпание ресурса
- •9.9 Упражнения
- •10.1 Введение
- •10.2 Вывод
- •10.2.1 Вывод встроенных типов
- •10.4.1.2 Поля вывода
- •10.4.1.4 Вывод целых
- •10.5.1 Закрытие потоков
- •10.5.2 Строковые потоки
- •X Целый параметр выдается в шестнадцатеричной записи;
- •11. Лекция: Проектирование и развитие: версия для печати и pda
- •11.1 Введение
- •11.2 Цели и средства
- •11.3 Процесс развития
- •11.3.1 Цикл развития
- •11.3.2 Цели проектирования
- •11.3.3 Шаги проектирования
- •11.3.3.1 Шаг 1: определение классов
- •11.3.3.2 Шаг 2: определение набора операций
- •11.3.3.3 Шаг 3: указание зависимостей
- •11.3.3.4 Шаг 4: определение интерфейсов
- •11.3.3.5 Перестройка иерархии классов
- •11.3.3.6 Использование моделей
- •11.3.4 Эксперимент и анализ
- •11.3.5 Тестирование
- •11.3.6 Сопровождение
- •11.3.7 Эффективность
- •11.4 Управление проектом
- •11.4.1 Повторное использование
- •11.4.2 Размер
- •11.4.3 Человеческий фактор
- •11.5 Свод правил
- •11.6 Список литературы с комментариями
- •12.1.1 Игнорирование классов
- •12.1.2 Игнорирование наследования
- •12.1.3 Игнорирование статического контроля типов
- •12.1.4 Гибридный проект
- •12.2 Классы
- •12.2.1 Что представляют классы?
- •12.2.2 Иерархии классов
- •12.2.3 Зависимости в рамках иерархии классов.
- •12.2.7 Отношения внутри класса
- •12.3 Компоненты
- •12.4 Интерфейсы и реализации
- •12.5 Свод правил
- •13. Лекция: Проектирование библиотек: версия для печати и pda
- •13.1 Введение
- •13.2 Конкретные типы
- •13.5.1 Информация о типе
- •13.6 Обширный интерфейс
- •13.7 Каркас области приложения
- •13.8 Интерфейсные классы
- •13.10 Управление памятью
11.2 Цели и средства
Цель программирования - создать продукт, удовлетворяющий пользователя. Важнейшим средством для достижении этой цели является создание программы с ясной внутренней структурой и воспитание коллектива программистов и разработчиков, имеющих достаточный опыт и мотивацию, чтобы быстро и эффективно реагировать на все изменения.
Почему это так? Ведь внутрення структура программы и процесс, с помощью которого она получена, в идеале никак не касаются конечного пользователя. Более того, если конечный пользователь почему-то интересуется тем, как написана программа, то что-то с этой программой не так. Почему, несмотря на это, так важны структура программы и люди, ее создавшие? В конце концов конечный пользователь ничего об этом не должен знать.
Ясная внутренняя структура программы облегчает:
тестирование,
переносимость,
сопровождение,
расширение,
реорганизацию и
понимание.
Главное здесь в том, что любая удачная большая программа имеет долгую жизнь, в течение которой над ней работают поколения программистов и разработчиков, она переносится на новую машину, приспосабливается к непредусмотренным требованиям и несколько раз перестраивается. Во все время жизни необходимо в приемлемое время и с допустимым числом ошибок выдавать версии программы. Не планировать все это - все равно, что запланировать неудачу.
Отметим, что, хотя в идеальном случае случае пользователи не должны знать внутреннюю структуру системы, на практике они обычно хотят ее знать. Например, пользователь может желать познакомиться в деталях с разработкой системы с целью научиться контролировать возможности и надежность системы на случай переделок и расширений. Если рассматриваемый программный продукт есть не полная система, а набор библиотек для получения программных систем, то пользователь захочет узнать побольше "деталей", чтобы они служили источником идей и помогали лучше использовать библиотеку.
Нужно уметь очень точно определить объем проектирования программы. Недостаточный объем приводит к бесконечному срезанию острых углов ("побыстрее передадим систему, а ошибку устраним в следующей версии"). Избыточный объем приводит к усложненному описанию системы, в котором существенное теряется в формальностях, в результате чего при реорганизации программы получение работающей версии затягивается ("новая структура намного лучше старой, пользователь согласен ждать ради нее"). К тому же возникают такие потребности в ресурсах, которые непозволительны для большинства потенциальных пользователей. Выбор объема проектирования - самый трудный момент в разработке, именно здесь проявляется талант и опыт. Выбор трудно сделать и для одного программиста или разработчика, но он еще труднее для больших задач, где занято много людей разного уровня квалификации.
Организация должна создавать программный продукт и сопровождать его, несмотря на изменения в штате, в направлении работы или в управляющей структуре. Распространенный способ решения этих проблем заключался в попытке сведения процесса создания системы к нескольким относительно простым задачам, укладывающимся в жесткую структуру. Например, создать группу легко обучаемых (дешевых) и взаимозаменяемых программистов низкого уровня ("кодировщиков") и группу не таких дешевых, но взаимозаменяемых (а значит также не уникальных) разработчиков. Считается, что кодировщики не принимают решений по проектированию, а разработчики не утруждают себя "грязными" подробностями кодирования. Обычно такой подход приводит к неудаче, а где он срабатывает, получается слишком громоздкая система с плохими характеристиками.
Недостатки такого подхода состоят в следующем:
слабое взаимодействие между программистами и разработчиками приводит к неэффективности, промедлению, упущенным возможностям и повторению ошибок из-за плохого учета и отсутствия обмена опытом;
сужение области творчества разработчиков приводит к слабому профессиональному росту, безынициативности, небрежности и большой текучести кадров.
По сути, подобные системы - это бесполезная трата редких человеческих талантов. Создание структуры, в рамках которой люди могут найти применение разным талантам, овладеть новым родом деятельности и участвовать в творческой работе - это не только благородное дело, но и практичное, коммерчески выгодное предприятие.
С другой стороны, нельзя создать систему, представить документацию по ней и бесконечно ее сопровождать без некоторой жесткой организационной структуры. Для чисто новаторского проекта хорошо начать с того, что просто найти лучших специалистов и позволить им решать задачу в соответствии с их идеями. Но по мере развития проекта требуется все больше планирования, специализации и строго определенного взаимодействия между занятыми в нем людьми. Под строго определенным понимается не математическая или автоматически верифицируемая запись (хотя это безусловно хорошо там, где возможно и применимо), а скорее набор указаний по записи, именованию, документации, тестированию и т.п. Но и здесь необходимо чувство меры. Слишком жесткая структура может мешать росту и затруднять совершенствование. Здесь подвергается проверке талант и опыт менеджера. Для отдельного работника аналогичная проблема сводится к определению, где нужно проявить смекалку, а где действовать по рецептам.
Можно рекомендовать планировать не на период до выдачи следующей версии системы, а на более долгий срок. Строить планы только до выпуска очередной версии - значит планировать неудачу. Нужно иметь организацию и стратегию развития программного обеспечения, которые нацелены на создание и поддержание многих версий разных систем, т.е. нужно многократное планирование успеха.
Цель проектирования в выработке ясной и относительно простой внутренней структуры программы, называемой иногда архитектурой, иными словами каркаса, в который укладываются отдельные программные фрагменты, и который помогает написанию этих фрагментов.
Проект - конечный результат процесса проектирования (если только бывает конечный продукт у итеративного процесса). Он является средоточием взаимодействий между разработчиком и программистом и между программистами. Здесь необходимо соблюсти чувство меры. Если я, как отдельный программист, проектирую небольшую программу, которую собираюсь написать завтра, то точность и полнота описания проекта может свестись к нескольким каракулям на обратной стороне конверта. На другом полюсе находится система, над которой работают сотни программистов и разработчиков, и здесь могут потребоваться тома тщательно составленных спецификаций проекта на формальном или полуформальном языке. Определение нужной степени точности, детализации и формальности проектирования является уже само по себе нетривиальной технической и административной задачей.
Далее будет предполагаться, что проект системы записывается как ряд определений классов (в которых частные описания опущены как лишние детали) и взаимоотношений между ними. Это упрощение, т.к. конкретный проект может учитывать: вопросы параллельности, использование глобального пространства имен, использование глобальных функций и данных, построение программы для минимизации перетрансляции, устойчивость, многомашинный режим и т.п. Но при обсуждении на данном уровне детализации без упрощения не обойтись, а классы в контексте С++ являются ключевым понятием проектирования. Некоторые из указанных вопросов будут обсуждаться ниже, а те, которые прямо затрагивают проектирование библиотек С++, будут рассмотрены в лекции 13. Более подробное обсуждение и примеры определенных методов объектно- ориентированного проектирования содержатся в [2].
Мы сознательно не проводили четкого разделения анализа и проектирования, поскольку обсуждение их различий выходит за рамки этой книги, и оно зависит от применяемых методов проектирования. Главное в том, чтобы выбрать метод анализа, подходящий для метода проектирования, и выбрать метод проектирования, подходящий для стиля программирования и используемого языка.
