Сообщений 3    Оценка 78        Оценить  
Система Orphus

Анализ программного кода на примере проектов Open Source

Автор: Спинеллис Диомидис
Издательство: Вильямс, 2004
528 страниц

Материал предоставил: Алексей Кирюшкин
Найти в магазинах
Купить в Озоне (302 руб.)
Купить в Болеро (232 руб.)
Купить в My-Shop.ru (283 руб.)

Аннотация

Содержание
Предисловие
От автора
Комментарии

Аннотация

Книга посвящена важному аспекту программирования, недостаточно освещенному в литературе - чтению и анализу программного кода на языках высокого уровня с целью доработки, извлечения готовых технических решений или изучения новых методов.
Даются ценные рекомендации по улучшению стиля программирования. Изложение проиллюстрировано большим количеством примеров, взятых из больших программных проектов с открытым кодом, находящихся на прилагаемом компакт-диске.
Книга предназначена для повышения квалификации программистов. Может быть полезна студентам и преподавателям соответствующих специальностей, а также начинающим программистам.

Содержание

Предисловие

1 Общие сведения
1.1 Зачем и как читать код
1.1.1 Код как литература
1.1.2 Код как сборник примеров
1.1.3 Отладка и внесение изменений
1.1.4 Усовершенствование кода
1.1.5 Повторное использование кода
1.1.6 Ревизия кода
1.2 Как читать эту книгу
1.2.1 Соглашения и обозначения
1.2.2 Диаграммы
1.2.3 Упражнения
1.2.4 Дополнительные материалы
1.2.5 Инструментальные средства
1.2.6 Краткое содержание книги
1.2.7 Языки
Дополниельная литература

2 Основные элементы программ
2.1 Пример полной программы
2.2 Функции и глобальные переменные
2.3 Циклы while, условные операторы и блоки
2.4 Операторы switch
2.5 Циклы for
2.6 Операторы break и continue
2.7 Символьные и логические выражения
2.8 Операторы goto
2.9 Реорганизация в малом
2.10 Циклы do и целочисленные выражения
2.11 Снова об управляющих структурах
Дополнительная литература

3 Сложные типы данных в языке C
3.1 Указатели
3.1.1 Связанные структуры данных
3.1.2 Динамисеское размещение структур данных
3.1.3 Передача аргументов по адресу
3.1.4 Обращение к элементам данных
3.1.5 Массивы как аргументы и результаты
3.1.6 Указатели на функции
3.1.7 Указатели как псевдонимы
3.1.8 Указатели и строки
3.1.9 Прямой доступ к памяти
3.2 Структуры
3.2.1 Группировка элементов данных
3.2.2 Возвращение нескольких результатов из функции
3.2.3 Отображение организации анных на устройстве
3.2.4 Программирование в объектно-ориентированном стиле
3.3 Объединения
3.3.1 Экономичное использование памяти
3.3.2 Реализация полиморфизма
3.3.3 Обращение к различным внутренним представлениям
3.4 Динамическое распределение памяти
3.4.1 Управление свободной памятью
3.4.2 Структуры с динамически распределеными массивами
3.5 Объявление новых типов с помощью typedef
Дополнительная литература

4 Структуры данных в C
4.1 Векторы
4.2 Матрицы и таблицы
4.3 Стеки
4.4 Очереди
4.5 Таблицы соответствий
4.5.1 Хэш-таблицы
4.6 Множества
4.7 Связаные списки
4.8 Деревья
4.9 Графы
4.9.1 Хранение узлов графа в памяти
4.9.2 Представление ребер графа
4.9.3 Хранение ребер графа в памяти
4.9.4 Свойства графа
4.9.5 Неявные структуры даных
4.9.6 Другие представления
Дополнительная литература

5 Сложные средства управления программами
5.1 Рекурсия
5.2 Исключительные ситуации
5.3 Распараллеливание
5.3.1 Аппаратное и программное распараллеливание
5.3.2 Модели управления распараллеливанием
5.3.3 Реализация потоков
5.4 Сигналы
5.5 Нелокальные переходы
5.6 Макроподстановки
Дополнительная литература

6 Анализ больших проектов
6.1 Методы проектирования и реализации
6.2 Организация проекта
6.3 Процесс формирования проекта
6.4 Конфигурирование
6.5 Управление версиями
6.6 Специальные программные средства
6.7 Тестирование
Дополнительная литература

7 Стандарты стиля программирования
7.1 Имена и организация файлов
7.2 Отступы в строках
7.3 Форматирование
7.4 Соглашения об именах
7.5 Программные конструкции
7.6 Стандартизация процесса разработки
Дополнительная литература

8 Документация
8.1 Разновидности документации
8.2 Чтение документации
8.3 Проблемы с документацией
8.4 Дополнительные документальные источники
8.5 Форматы документации в проектах с открытым кодом
Дополнительная литература

9 Архитектура
9.1 Общие принципы построения систем
9.1.1 Централизованная модель и распределенные архитектуры
9.1.2 Потоковые архитектуры
9.1.3 Объектно-ориентированные архитектуры
9.1.4 Многоуровневые архитектуры
9.1.5 Иерархии
9.1.6 Усечение
9.2 Модели управления
9.2.1 Системы, управляемые событиями
9.2.2 Системный диспетчер
9.2.3 Переходы между состояниями
9.3 Группировка элементов кода
9.3.1 Модули
9.3.2 Пространства имен
9.3.3 Объекты
9.3.4 Нетипизированные формы
9.3.5 Абстрактные тиы данных
9.3.6 Библиотеки
9.3.7 Процессы и фильтры
9.3.8 Компоненты
9.3.9 Хранилища данных
9.4 Перенос архитектуры
9.4.1 Рабочие среды
9.4.2 Генераторы кода
9.4.3 Структурные шаблоны
9.4.4 Проблемно-ориентированные архитектуры
Дополнительная литература

10 Вспомогательные программные средства
10.1 Регулярные выражения
10.2 Редактор как браузер кода
10.3 Программа поиска grep
10.4 Поиск различий между файлами
10.5 Создание собственных программных средств
10.6 Использование компиляторов для нализа кода
10.7 Просмотр и визуальное форматирование кода
10.8 Работа с кодом на этапе выполнения
10.9 Различные подходы и методы
Дополнительные программы и литература

11 Практический пример
11.1 Подготовительный этап
11.2 Стратегический этап
11.3 Перенос кода
11.4 Тестирование и отладка
11.5 Документация
11.6 Некоторые наблюдения

А Обзор прилагаемого кода

Б Благодарности авторам кода

В Указатель файлов исходного кода

Г Лицензионные соглашения
Г1 ACE
Г2 Apache
Г3 ArgoUML
Г4 DemoGL
Г5 hsqldb
Г6 NetBSD
Г7 OpenCL
Г8 Perl
Г9 qtchat
Г10 socket
Г11 vcf
Г12 X Window System

Д Свод рекомендаций по анализу кода
Глава 1 Общие сведения
Глава 2 Основные элементы программ
Глава 3 Сложные типы данных в языке C
Глава 4 Структуры данных в C
Глава 5 Сложные средства управления программами
Глава 6 Анализ больших проектов
Глава 7 Стандарты стиля программирования
Глава 8 Документация
Глава 9 Архитектура
Глава 10 Вспомогательные программные средства
Глава 11 Практический пример

Список литературы

Источники эпиграфов

Предметный указатель

Предисловие

Дэйв Томас (Dave Thomas), компания The Pragmatic Programmers LLC

Мы - программисты. Наша работа (а часто и наша страсть) состоит в том, чтобы писать программы для самых разных целей. Пользователи получают от нас совсем не гектары графиков, тонны описаний и стопки проектной документации выше человеческого роста. Все это - лишь средство для воплощения замысла в конечный продукт. А самим конечным продуктом является программа.

Именно написанию программ нас и учат. Раз уж работа состоит в том, чтобы написать программный код, значит, надо учиться писать программный код. Этому посвящены предметы университетской программы, а на курсах повышения квалификации мы еще и осваиваем новые библиотеки и интерфейсы. И именно в этом состоит величайшая проблема индустрии программирования. Потому что основной способ научиться писать хороший код - это читать побольше кода. Высококачественного и низкокачественного, на ассемблере и языках высокого уровня, написанного много лет назад за тысячи километров от вас и позавчера вами самими. Если этого не делать, то постоянно приходится заново изобретать велосипед, повторяя как успехи, так и ошибки прошлого.

Интересно, многие ли выдающиеся писатели никогда не читали романов, написанных их предшественниками? А сколько художников не трудились анализировать манеру письма великих живописцев? Как много хирургов в свое время не наблюдали за операциями более опытных коллег? Существуют ли на свете командиры экипажей пассажирских авиалайнеров, никогда не сидевшие в кресле второго пилота и не наблюдавшие, как нужно выполнять взлет и посадку?

Но именно так, согласно общепринятой практике, приходится работать программистам. Им неизменно говорят: ''На этой неделе наша задача - написать то-то и то-то''. Программиста учат азбуке - синтаксису языка и построению элементарных конструкций, а потом требуют, чтобы он написал программу, эквивалентную по качеству роману хорошего писателя.

По иронии судьбы, именно сейчас наступило самое благодатное время для чтения кода. Благодаря огромному вкладу всемирного сообщества авторов открытого кода по глобальным компьютерным сетям рассеяны гигабайты исходного кода, который осталось только взять и прочитать. Выберите любой язык, и вы найдете сколько угодно программ на нем. Выберите проблему, и вы обнаружите огромное количество ее решений. На любом уровне - от микропрограммирования до высокоуровневых функций и объектов - в настоящее время стал доступен огромный объем исходного кода.

Читать и анализировать код очень интересно. Лично я это обожаю. Я ищу в читаемом мною коде удачные решения, хитрые трюки, ошибки и ловушки. Иногда попадаются настоящие жемчужины, пусть и небольшие. До сих пор помню испытанное мною удовольствие, когда я случайно обнаружил программу преобразования из двоичной записи в восьмеричную на языке ассемблера для машины PDP-11, выполняющую вывод до шести восьмеричных цифр в одном цикле без счетчика.

Иногда я читаю код как литературное произведение - нечто вроде романа, купленного в аэропорту перед долгим перелетом. Меня развлекает удачно выстроенный сюжет и неожиданные авторские решения. Прекрасным примером чего-то подобного может служит программа gpic Джеймса Кларка (James Clark), которая входит в состав его GNU-пакета grof f. В ней с помощью исключительно компактной и элегантной структуры реализуется очень сложная задача - построение декларативного аппаратно-независимого языка для рисования графических изображений. Чтение этого кода подвигло меня на попытку структурировать свой собственный код столь же изящно.

Бывает, что я читаю код с более критических позиций. Этот процесс более медленный, поскольку нужно постоянно задавать себе вопросы типа ''Почему это написано именно так?'' или ''Какие соображения побудили автора выбрать именно этот способ?'' Иногда такой режим чтения кода вызван необходимостью найти в нем ошибку. Тогда я ищу конструкции и ключевые места, которые могут дать подсказку. Например, если автор плохо защитил совместно используемую структуру данных в одной части кода, можно заподозрить, что это случилось и в другой, и таким образом найти источник проблемы. Обнаруженные несоответствия могут служить проверкой и моего собственного уровня понимания. Часто я принимаю какой-то фрагмент кода за проблематичный или неграмотный, но при более тщательном анализе оказывается, что он написан искусно и безошибочно. Тогда я сам учусь чему-то новому.

Фактически чтение и анализ кода представляют собой один из эффективных путей устранения ошибок и недоработок в программах. Роберт Гласе (Robert Glass), один из рецензентов этой книги, сказал: ''Путем грамотного просмотра исходного кода в программном продукте можно устранить более 90% ошибок еще до первого тестирования''. В той же статье он ссылается на результаты одного исследования, которые гласят: ''Если читать программу, сконцентрировавшись на качестве ее исходного кода, можно найти на 90% ошибок больше, чем если сосредоточиться на выполняемых ею операциях''. Интересно, что анализируя фрагменты кода, используемые в этой книге, я обнаружил пару ошибок и несколько сомнительных программных конструкций. Причем эти фрагменты взяты из программ, работающих на десятках тысяч рабочих мест по всему миру. Ни одна из ошибок не имеет критического характера, но сам факт доказывает, что всегда есть куда расти. Навыки чтения и анализа кода приносят непосредственную практическую пользу. Возможно, читатель уже и сам это понял, если когда-нибудь читал код своих коллег, которые такими навыками не обладают.

К тому же существует еще и техническая поддержка программ - младшая и нелюбимая сестра их разработки. Точной статистики здесь нет, но большинство исследователей сходятся в том, что примерно половину времени, выделенного на поддержку, приходится проводить за чтением написанного кода: добавлять новые функциональные возможности, исправлять ошибки, интегрировать в новые среды и т.п. Здесь уже навыки чтения и анализа кода приобретают критическое значение. Предположим, есть программа из 100 000 строк кода, содержащая ошибку, и у вас ровно час на исправление этой ошибки. С чего начать? Как узнать, что делает тот код, который находится перед глазами? Как заранее оценить влияние изменения в программе, которое вы собираетесь внести?

В силу всего сказанного и многого другого мне нравится эта книга. В ее основе лежит четкий практический подход. Вместо абстрактных академических рассуждений здесь говорится о конкретном коде. В книге анализируются сотни фрагментов кода, рассказывается о хитроумных приемах, ловушках и (что наиболее важно) стандартных подходах. Код рассматривается в контексте его рабочей среды - как она влияет на него при взаимодействии. Говорится и о программных средствах, применяемых в деле анализа кода, - от стандартных типа grep или find до наиболее экзотических. Подчеркиваются важность разработки таких средств и цель их создания: писать программы, чтобы анализировать существующие программы. Поскольку книга насквозь пронизана практицизмом, весь рассмотренный в ней код удобно организован и помещен на прилагаемый компакт-диск.

Эта книга обязательна для изучения студентами, имеющими отношение к программированию, и должна стоять на полке каждого программиста-практика. Если все сообщество разработчиков программ будет уделять больше внимания чтению и анализу кода, то мы сэкономим много времени и труда, а также снизим денежные затраты в нашей индустрии. Кроме того, мы еще и получим море удовольствия от этой работы.

От автора

Спинеллис Диомидис

Чтение и анализ кода - это повседневное занятие любого специалиста в области компьютерного программирования. Однако его практически никогда не преподают как учебный предмет и не рассматривают как строгий метод при разработке программ.

Возможно, первоначальной причиной такого плачевного положения дел была недостаточность или практическое отсутствие реального и высококачественного программного кода, открытого для общего доступа. Фирмы-разработчики чаще всего защищают исходный код как свою коммерческую тайну и очень редко позволяют посторонним читать, комментировать, экспериментировать и активно изучать такой код. В тех немногих случаях, когда исходный код важных коммерчески защищенных приложений выходил из-под контроля разработчиков и становился общедоступным, он немедленно вызывал бурю интереса и ряд творческих разработок на его основе. Например, целое поколение программистов училось по книге Джона Лайонза Комментарии к операционной системе UNIX (John Lions, Commentary on the Unix Operating System), в которой приведен весь исходный код ядра операционной системы UNIX в ее шестом издании с пояснениями автора. Первоначально книга Лайонза была написана под эгидой и на деньги корпорации AT&T для использования в учебном курсе по этой операционной системе и не предназначалась для распространения среди широкой общественности. Тем не менее нелегальные фотокопии этой книги вместе с копиями ее копий вращались в среде программистов годами.

В последние несколько лет популярность программ с открытым кодом возросла, и теперь мы располагаем огромным объемом исходных текстов, которые можно свободно читать и анализировать. В настоящее время доступны в форме с открытым исходным кодом такие популярнейшие программные продукты, как Web-сервер Apache, интерпретатор языка Perl, операционная система GNU/Linux, сервер доменных имен BIND, почтовый агент sendmail. Поэтому мне посчастливилось иметь под рукой достаточно программ с открытым кодом, чтобы написать эту книгу сразу и как ''букварь'' и как ''хрестоматию'' по анализу программного кода. Моя цель состоит в том, чтобы дать читателю достаточно знаний и вооружить его средствами для чтения кода, написанного другими программистами. Используя практические примеры, взятые из реально работающих программ с открытым кодом, я постарался охватить все основные принципы и концепции, относящиеся к анализируемому коду: программные конструкции, типы данных, структуры данных, управление программой, организацию проекта, стандарты, документирование, архитектуры. В этой же серии книг я постараюсь рассмотреть особенности организации интерфейсов и приложений, интернационализацию и переносимость, библиотеки общего пользования и операционные системы, код низкого уровня, декларативные и доменные языки, языки разработки сценариев, смешанные языковые системы.

Насколько мне известно, в этой книге чтение и анализ программного кода впервые рассматриваются как самостоятельный вид деятельности программиста, ценный сам по себе. Первый блин- всегда комом, поэтому недоработки неизбежны. Какая-то часть материала могла быть изложена лучше, кое-что пропущено, неизбежны и ошибки. Я твердо убежден, что анализ кода необходимо систематически преподавать и использовать как строгий метод для повышения квалификации программиста. Поэтому надеюсь, что книга подстегнет интерес к анализу кода в университетских кругах. Соответствующие курсы и предметы, возможно, будут включены в учебные планы по компьютерным специальностям, и через несколько лет наши студенты будут так же успешно учиться программировать на примере проектов с открытым кодом, как студенты филологических специальностей изучают языки по произведениям великих писателей.

Многие примеры кода в этой книге взяты из исходного текста дистрибутива NetBSD. Это бесплатно распространяемая, очень хорошо переносимая UNIX-подобная операционная система, доступная в настоящее время для целого ряда аппаратных платформ от 64-разрядных машин AlphaServer до портативных и карманных компьютеров. Четкая структура и высокопрофессиональная реализация делают эту систему прекрасным выбором как для производственно-прикладных, так и для научно-исследовательских компьютерных систем. Я выбрал систему NetBSD среди целого ряда столь же достойных и не менее популярных UNIX-подобных систем (GNU/Linux, FreeBSD, OpenBSD) по той причине, что ключевыми требованиями при ее создании были строгость, выразительность и хорошая организация кода. Поэтому примеры из нее особенно удачны. Как говорят разработчики системы, некоторые программные продукты, похоже, сделаны по принципу ''раз работает - значит, написано правильно''. В то же время в проекте NetBSD используется принцип ''пока не написано правильно - в работу не пускать''. Кроме того, и некоторые другие принципы построения системы NetBSD хорошо соответствуют целям и задачам этой книги. В частности, в проекте NetBSD избегают обременительного лицензирования, стараются сделать систему максимально переносимой на все платформы и хорошо взаимодействующей с другими системами, удовлетворяют стандартам открытых систем настолько, насколько это удобно практически. Код, использованный в этой книге, взят из версии export-19980407, уже ставшей историей. В нескольких примерах приводятся найденные мною ошибки. Поскольку код NetBSD постоянно дорабатывается, есть риск, что в следующих версиях эти ошибки уже исправлены, и читатель не получит уникальной возможности проанализировать их, если взять примеры из более позднего кода.

Остальные программы, фрагменты из которых используются в книге, были выбраны по тем же причинам: высокое качество кода, структура, организация, практичность, распространенность, доступный уровень лицензирования. Я старался тщательно подбирать языки, постоянно разыскивая подходящие примеры из C++ и Java. Но в тех случаях, если понятие или принцип можно было проиллюстрировать на разных языках, в качестве наименьшего общего знаменателя выбирался язык С.

Некоторые примеры кода я привожу для того, чтобы проиллюстрировать плохой - небезопасный, трудно переносимый, неудобочитаемый - стиль программирования. Признаю, что его авторы могут воспринять это как удар ниже пояса - ведь они предоставляли код в надежде помочь развитию открытых программных систем и надеялись на конструктивное улучшение вместо издевательской критики. Заранее приношу свои извинения всем возможным оскорбленным авторам исходного кода. В свою защиту могу сказать, что в большинстве случаев критика направлена не на конкретный фрагмент, а скорее на стиль или практику, которых следует избегать. Очень часто пример ''как не надо делать'' относится к далекому прошлому- это гадкий утенок, который уже давно стал прекрасным лебедем. Просто в свое время было необходимо писать именно так из-за технических или других ограничений. Бывает и так, что плохой стиль программирования критикуется мною вообще вне всякого контекста. В любом случае надеюсь, что критика будет воспринята доброжелательно и с юмором. Заранее признаю, что мои собственные программы содержат похожие, если не худшие, упущения и недочеты.

Комментарии

Алексей Кирюшкин

Эта книга - альбом иллюстраций. Автор последовательно перебирает различные аспекты программирования - от основ языка к способам организации проектов, стилям программирования, ведению документации, архитектурам построения систем и инструментам разработчика - и каждый рассматриваемый аспект и способы его исполнения иллюстрирует примерами из 500 МБ исходных текстов 12-ти Open Source проектов, находящихся на компакт-диске к книге.

В отличии от других книг, показывающих и объясняющих, как, с точки зрения автора, делать можно и нужно, Диомидис рассказывает о том, как это уже сделано в реальных, живых проектах.

Книг такой направленности, к сожалению, очень мало, и автор, по доброте душевной решивший охватить столь широкий круг вопросов, вынужденно не особенно углубляется в рассмотрение каждого из них, хотя, право же, большинство глав заслуживают отдельной книги, по толщине сравнимой с этой.

Особо хочется обратить внимание преподавателей программирования на упражнения-задания, сопровождающие каждую рассматриваемую тему - вашим студентам не придется скучать :)

    Сообщений 3    Оценка 78        Оценить