Личный опыт разработки ПО

Сборник рецептов

Использование Doxygen для документирования кода

комментариев 14

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

Что такое Doxygen?

Doxygen – это кроссплатформенная система документирования кода с поддержкой языков C++, C, Java, Objective-C, PHP, C# (список можно уточнить на сайте проекта).

Для создания документации достаточно просто писать комментарии в коде, придерживаясь нескольких простых правил.

Doxygen умеет анализировать исходный код проекта и создавать удобную документацию в формате HTML, Latex, RTF, XML, man, CHM.

Общие соображения

  1. Написание документации должно быть максимально простым, чтобы разработчики не "забывали" это делать. Отсюда вывод, что сложность форматирования комментариев должна быть минимальной.

    Хорошо:

    namespace A
    {
    /**
    Имя класса
     
    Описание класса
    */
    	class B
    	{
    	};
    }

    Плохо:

    namespace A
    {
    	/**
    	 * Имя класса
    	 * 
    	 * Описание класса
    	 */
    	class B
    	{
    	};
    }

    Почему второй вариант хуже? Очевидно, из-за необходимости выравнивать комментарии на одном уровне с комментируемой сущностью, а также из-за избыточных символов *. Это может показаться надуманным, но при написании комментариев из нескольких строк проблема проявляется, а при поддержке кода и вовсе становится кошмаром. Вы можете возразить, что подобный стиль делает код "рваным", но в любом случае комментирование интерфейсов делает код менее читаемым. К счастью все современные редакторы кода позволяют легко свернуть блоки с комментариями, что позволит взглянуть на код без помех.

  2. Много документации – плохо, так как мало кто будет читать длинные мануалы. Из этого следует, что документированы должны быть только открытые (public) и защищенные (protected) интерфейсы. Закрытые (private) интерфейсы – часть внутренней реализации и не должны быть в руководстве.

Что нам понадобится?

Нам понадобится сделать две вещи:

  1. Установить Doxygen, если он еще не установлен.
  2. Установить Graphviz. Graphviz – это свободно распространяемый пакет утилит для визуализации данных. Нам он нужен для того, чтобы Doxygen мог показать в документации отношения наследования, графы вызовов и прочую информацию в виде наглядных изображений.

Использование Doxygen

Использовать Doxygen просто – для этого надо просто запустить программу указав ей путь к файлу с настройками. Файл с настройками представляет собой простой текстовой файл, который можно редактировать как в текстовом редакторе, так и с помощью специальных программ, например Doxygate.

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

Я предпочитаю редактировать этот файл вручную, тем более, что его достаточно настроить один раз под свои потребности и затем в новых проектах изменять одну строку – имя проекта. В конце заметки будет представлен используемый мной конфигурационный файл.

Комментирование в стиле Doxygen

Doxygen поддерживает несколько стилей комментариев. Я придерживаюсь следующего:

/**
Комментарии
*/

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

Есть несколько директив, которые помогают Doxygen составить грамотную документацию. Вот основные:

@brief Краткое описание комментируемой сущности.

Пример:

@brief Функция для поиска пользователя в базе данных

@detailed Подробное описание сущности, то что будет показано, когда вы нажмете в документации рядом с коротким описанием ссылку "Подробней". На мой взгляд использоваться должно как можно реже, в силу того, что короткое описание должно точно отражать идею использования сущности, а использование ее не должно сопровождаться неожиданными предусловиями.

Пример:

@detailed Данная функция делает выборку из базы данных 
по имени пользователя и возвращает структуру с информацией 
о нем. Ожидается, что соединение с базой данных установлено 
и пользователь существует

@param Параметры передаваемые функции.

Пример:

@param name Имя пользователя

@return Возвращаемое функцией значение.

Пример:

@return Информация о пользователе

@throw Исключения выбрасываемые функцией.

Пример:

@throw DatabaseError Если произошла ошибка при подключении 
к базе данных

Пример комментариев для класса:

/**
@brief Класс для работы с базой данных
@detailed Осуществляет подключение к базе при создании 
и закрывает соединение при уничтожении
*/
class Database
{
public:
/**
@brief Конструктор
@param connectionString Строка подключения к базе данных
@throw ConnectionError Если подключение не удалось
*/
	explicit Database(const std::string& connectionString);
/**
@brief Поиск пользователя в базе данных
@detailed Данная функция делает выборку из базы данных 
по имени пользователя и возвращает структуру с информацией 
о нем. Ожидается, что соединение с базой данных установлено 
и пользователь существует
@param name Имя пользователя
@return Информация о пользователе
@throw DatabaseError Если произошла ошибка при подключении 
к базе данных
@throw InvalidRequest Если пользоваделя в базе не существует
*/
	CustomerPtr GetCustomer(const std::string& name);
};

Этого достаточно для 99% кода, но остается вопрос комментирования на уровне проекта, а не файла. Для этого служат следующие директивы:

@mainpage Основная страница проекта, то с чего начинается просмотр документации.

Пример:

@mainpage Приложение для учета пользователей

@page Дополнительные страницы проекта. Я рассматриваю их как логически обособленные части проекта.

Пример:

@page Database Database
Утилиты для работы с базой данных

@ref Ссылки на страницы проекта, с их помощью можно организовать например ссылки с главной страницы проекта на страницы подпроектов.

Пример:

@ref Database Утилиты для работы с базой данных

Для организации четкой структуры я рекомендую в каждом подпроекте создавать файл description.h в котором будет директива @page, описание для чего нужен этот подпроект и принципы работы с ним.

В свою очередь в корне проекта я также создаю файл description.h в котором немного рассказано о проекте в целом и приведены ссылки на его части:

/**
@mainpage Приложение для учета пользователей
Состоит из следующих частей:
- @ref Database Утилиты для работы с базой данных
*/

Чтобы привести фрагмент кода (например пример работы с классом) используется конструкция @code@endcode:

/**
Пример использования Foo:
@code
Foo f();
f.Run();
@endcode
*/

Списки можно создавать с помощью символа (минус). Пример:

/**
Список:
- Первый пункт
- Второй пункт
*/

Перечисления я оформляю так:

/**
@brief Режимы устройства
*/
enum Mode
{
	Mode_On,	/**< Включено */
	Mode_Off	/**< Выключено */
};

В большинстве случаев приведенных директив достаточно, с полным списком вы можете ознакомиться в руководстве.

Ложка дегтя

Обратите внимание! Очень ВАЖНО перед объявлением пространства имен повторять его имя в комментарии Doxygen. Похоже на баг (версия 1.6.2), но без этого содержимое пространства не попадет в документацию. Пример:

/**
namespace A
@brief Пространство имен A
*/
namespace A
{
}

Символ @ в конструкции namespace отсутствует!

Файл с настройками Doxygen

Как уже упоминалось, для работы Doxygen нужен файл с настройками. Программа умеет создавать файл с параметрами по умолчанию:

doxygen -g

После этого будет сгенерирован файл с именем Doxyfile содержащий настройки по умолчанию. Вы можете отредактировать его под свои нужды, что сделать довольно просто благодаря содержащимся в нем пояснениям.

Рассмотрю некоторые из пунктов которые я изменяю:

PROJECT_NAME Имя проекта.
QUIET Допустимые значения YES и NO. Я ставлю YES, для того чтобы предупреждения не терялись среди обилия информации о работе программы.
WARN_NO_PARAMDOC YES для вывода предупреждений о недокументированных аргументах функции.
INPUT Путь к анализируемому коду. Я рекомендую в корне проекта создать директорию docs содержащую Doxyfile с настройками, в таком случае значение этого параметра будет ../

FILE_PATTERNS Шаблон для имени анализируемых файлов. Поскольку документироваться должны только открытые интерфейсы, то очевидно, что следует анализировать только заголовочные файлы: *.h

RECURSIVE Рекурсивно анализировать файлы в поддиректориях – YES.
EXCLUDE_PATTERNS Исключение из анализа директорий соответствующих маске.

Пример:

EXCLUDE_PATTERNS = */.svn/* */build/* */tests/* */sources/*
HAVE_DOT YES, если установлен Graphviz и требуется визуализация связей.

Очень разумно будет один раз написать свою конфигурацию для Doxygen и в новых проектах менять лишь один параметр – PROJECT_NAME.

Мой конфигурационный файл приведен чуть ниже. Он настроен на вывод предупреждений если не были документированы какие-либо сущности.

Файлы к заметке

Мой Doxyfile.

Проект с комментариями для Doxygen.

Пример готовой документации в формате HTML сгенерированной Doxygen.

Для создания документации перейдите в директорию docs и запустите doxygen.

7th Февраль 2010
23:00

14 комментариев к 'Использование Doxygen для документирования кода'

Подписаться на комментарии по RSS или TrackBack.

  1. Спасибо! Очень полезная инфа.

    Apple

    25 февраля 10 20:52

  2. Спасибо! Хоть и использовал doxygen, некоторые вещи делал криво.

    Только в листингах исправьте &

    Obey-Kun

    26 февраля 10 2:23

  3. Благодарю за внимательность!

  4. Спасибо, за хороший материал

    Академик

    4 марта 10 5:28

  5. Есть вопрос как к специалисту, пользующемуся doxygen. При генерации документации, если в проекте наряду с классами присутствуют статические структуры, doxygen включает перечень структур в раздел описания классов. Может быть подскажете значение какого ключа в конфигурационном файле следует поменять для того чтобы перечень структур не появлялся в перечне описания классов?

    Дмитрий

    1 июня 10 15:10

  6. Дякую за хорошу інформацію. Дуже допомогло

    traveller

    3 июля 10 19:30

  7. Спасибо, мне было полезно это почитать!

    Tim

    6 августа 10 0:10

  8. Абсолютно ублюдочный стиль комментариев. За такое надо бить ногами.

    Просто какая-то рубрика «вредные советы».

    Если чо,

    1) @brief можно явно не писать, да и @detailed при определенной настройке тоже;

    2) doxygen убирает лишние пробелы, так что никакой необходимости писать комментарий от начала строки нет, так что спокойно можно выравнивать комментарии вместе с кодом, как все нормальные люди и делают.

    Kerbadun

    24 января 11 4:00

  9. Если ты попробуешь прочесть статью, то узнаешь почему выбран именно такой стиль.

  10. Почему второй вариант хуже? Очевидно, из-за необходимости выравнивать комментарии на одном уровне с комментируемой сущностью, а также из-за избыточных символов *.

    Все нормальные редакторы делают это за программиста :)

    ikalnitsky

    28 августа 11 12:24

  11. Хорошая статья, спасибо! Сам только сел с ним разбираться)

    zendframework

    3 октября 11 15:26

  12. Вообще, тоже всегда был против начала строки комментариев со звёздочки. Пока не пришлось пользоваться поиском одной IDE, в которой в результатах поиска выводились только те строки в которых найдено совпадение.
    И вот при поиске в своём коде постоянно не мог понять, то ли закомментированный код, то ли рабочий.
    В коде других разработчиков использовавших звёздочки, таких проблем не возникало.

    Павел

    11 сентября 13 18:36

  13. ??????????????? ?????????????? [url=http://ddyfl.swu.edu.cn/zzyggglxy/upload/monclerdown.html]?????? ????? ???[/url] ????? ???????????????????????? [url=http://www.gfrasidence.com/category-c-13.html]CELESTE STEIN[/url] ?????????????????????????????? [url=http://www.onlineshoptokyoja.com/category-c-41.html]http://www.onlineshoptokyoja.com/category-c-41.html[/url] ?? ??????????????????????????? [url=http://www.salvage3selvage.com/category-c-9.html]????? ????[/url] ??????????????????????????? ?? [url=http://www.tropicalfloralshirts.com/category-c-30_31.html]http://www.tropicalfloralshirts.com/category-c-30_31.html[/url] ?????????????????????????????????????????????? ?????????????

    TydayAxonalal

    10 февраля 14 1:04

  14. > Абсолютно ублюдочный стиль комментариев. За такое надо бить ногами.

    Абсолютно ублюдочный комментатор. Не можешь по-человечески без оскорблений критику донести, нех ходить по чужим сайтам.
    А за статью спасибо.

    Ирина

    6 мая 14 15:14

Оставить комментарий