詳細設計書なんて、書きたくない・・・・Doxygenを使って自動生成してみる

# はじめに
お客様に提案をしているときの会話です。

お客様：「詳細設計書は作りますか」
私：「昔ながらの詳細設計（ロジックを日本語で書くもの）は作りません。クラス図とか、シーケンス図は複雑であれば作りますが、今回のシステムはそこまで必要なものはないものなので、割愛しようと思っています。」
お客様：「保守をお願いするかどうか未定なので、場合によっては引継ぎのために作ってもらうかもしれません」
私：「・・・・」

といった感じで、私がこの業界に入った30年前は、確かにプログラムを作る前に、詳細設計書と呼ばれるプログラムを日本語で書いていました。
最近、詳細設計と呼ばれるものを作った記憶がなく、無駄なものは作りたくないなぁという思いから、コードから自動生成できないかなと思って、いろいろ試してみました。

# Doxygenって
いろいろ調べてみると、[Doxygen](https://www.doxygen.nl/) にたどり着きました。

色々な言語に対応した、ドキュメントジェネレータです。アウトプットもHTMLだけでなくMarkdownや、PDF、Wordでも出力できるようです。

また、Windows版、Linux版、Mac版といろんな環境で利用できるように準備されています。


# やってみよう

## インストール
とりあえず、今回はWSL上のUbuntuでやってみようと思います。
doxygenが本体で、graphvizはクラス図とかを生成するために利用します。

```bash
sudo apt install doxygen
sudo apt install graphviz
```

これでバージョン確認。2024/7/1時点で、1.8.17となりました（最新は、1.11.0）のようですが、やりたいことはできそうなので、このバージョンでOKとします。

```bash
doxygen --version
```

## Doxyfileを作る
Doxygenを実行するためには、Doxyfileという設定ファイルが必要です。まずはひな形を生成します。
```bash
doxygen -g
```

Doxyfileができたら、以下のような修正を加えます。
設定値については、Doxygenの公式を参照するとよりよいと思います。

```diff
-OUTPUT_DIRECTORY       =
+OUTPUT_DIRECTORY       = "docs"

-OUTPUT_LANGUAGE        = English
+OUTPUT_LANGUAGE        = Japanese

-OPTIMIZE_OUTPUT_JAVA   = NO
+OPTIMIZE_OUTPUT_JAVA   = YES

-EXTRACT_ALL            = NO
+EXTRACT_ALL            = YES

-EXTRACT_PRIVATE        = NO
+EXTRACT_PRIVATE        = YES

-EXTRACT_PRIV_VIRTUAL   = NO
+EXTRACT_PRIV_VIRTUAL   = YES

-EXTRACT_PACKAGE        = NO
+EXTRACT_PACKAGE        = YES

-EXTRACT_STATIC         = NO
+EXTRACT_STATIC         = YES

-EXTRACT_LOCAL_CLASSES  = YES
+EXTRACT_LOCAL_CLASSES  = NO

-INPUT                  =
+INPUT                  = "src/main"

-RECURSIVE              = NO
+RECURSIVE              = YES

-REFERENCED_BY_RELATION = NO
+REFERENCED_BY_RELATION = YES

-REFERENCES_RELATION    = NO
+REFERENCES_RELATION    = YES

-ALPHABETICAL_INDEX     = YES
+ALPHABETICAL_INDEX     = NO

-GENERATE_LATEX         = YES
+GENERATE_LATEX         = NO

-UML_LOOK               = NO
+UML_LOOK               = YES

-UML_LIMIT_NUM_FIELDS   = 10
+UML_LIMIT_NUM_FIELDS   = 50

-TEMPLATE_RELATIONS     = NO
+TEMPLATE_RELATIONS     = YES

-CALL_GRAPH             = NO
+CALL_GRAPH             = YES

-CALLER_GRAPH           = NO
+CALLER_GRAPH           = YES

-DOT_IMAGE_FORMAT       = png
+DOT_IMAGE_FORMAT       = svg

-DOT_GRAPH_MAX_NODES    = 50
+DOT_GRAPH_MAX_NODES    = 100

```
| 設定項目                  | 説明                                                                                       |
|---------------------------|--------------------------------------------------------------------------------------------|
| OUTPUT_DIRECTORY          | ドキュメントの出力ディレクトリ。                                                           |
| OUTPUT_LANGUAGE           | ドキュメントの出力言語。                                                                  |
| OPTIMIZE_OUTPUT_JAVA      | Java向けに出力を最適化するかどうか。                                                       |
| EXTRACT_ALL               | 全てのメンバーを抽出するかどうか。                                                         |
| EXTRACT_PRIVATE           | プライベートメンバーを抽出するかどうか。                                                   |
| EXTRACT_PRIV_VIRTUAL      | プライベートな仮想メンバーを抽出するかどうか。                                             |
| EXTRACT_PACKAGE           | パッケージメンバーを抽出するかどうか。                                                     |
| EXTRACT_STATIC            | スタティックメンバーを抽出するかどうか。                                                   |
| EXTRACT_LOCAL_CLASSES     | ローカルクラスを抽出するかどうか。                                                         |
| INPUT                     | ソースファイルの入力ディレクトリ。                                                         |
| RECURSIVE                 | 入力ディレクトリを再帰的に検索するかどうか。                                               |
| REFERENCED_BY_RELATION    | 被参照関係を生成するかどうか。                                                             |
| REFERENCES_RELATION       | 参照関係を生成するかどうか。                                                               |
| ALPHABETICAL_INDEX        | アルファベット順の索引を生成するかどうか。                                                 |
| GENERATE_LATEX            | LaTeX形式のドキュメントを生成するかどうか。                                                |
| UML_LOOK                  | UMLスタイルの図を生成するかどうか。                                                        |
| UML_LIMIT_NUM_FIELDS      | UML図に表示するフィールドの最大数。                                                         |
| TEMPLATE_RELATIONS        | テンプレートの関係を表示するかどうか。                                                     |
| CALL_GRAPH                | 呼び出しグラフを生成するかどうか。                                                         |
| CALLER_GRAPH              | 呼び出し元グラフを生成するかどうか。                                                       |
| DOT_IMAGE_FORMAT          | DOTグラフの出力フォーマット。                                                              |
| DOT_GRAPH_MAX_NODES       | DOTグラフに表示する最大ノード数。                                                           |



## コメントの書き方
コメントの書き方はほぼJavadocと同じです。

クラスのコメント
```java
/**
 * @brief デモ用のシンプルなクラス。
 *
 * このクラスには2つの整数を加算するメソッドが含まれています。
 */
```

メソッドのコメント
```java
/**
 * @brief 2つの整数を加算します。
 *
 * このメソッドは2つの整数を入力として受け取り、その合計を返します。
 *
 * @param x 加算する最初の整数。
 * @param y 加算する二番目の整数。
 * @return 2つの整数の合計。
 */
```

その他コメントの一覧は以下の通り
| コメント形式              | 説明                                                                                      |
|---------------------------|-------------------------------------------------------------------------------------------|
| `@brief`                  | 簡潔な説明を記述します。1行で概要を説明するのに適しています。                              |
| `@details`                | 詳細な説明を記述します。複数行に渡って、より具体的な情報を提供します。                      |
| `@param`                  | メソッドの引数を説明します。                                                               |
| `@return`                 | メソッドの戻り値を説明します。                                                             |
| `@file`                   | ファイルの説明を記述します。                                                               |
| `@author`                 | 作者の名前を記述します。                                                                   |
| `@version`                | バージョン情報を記述します。                                                               |
| `@date`                   | 日付を記述します。                                                                         |
| `@see`                    | 参照リンクを記述します。                                                                   |
| `@deprecated`             | 非推奨であることを通知します。                                                             |

## 生成する
以下のコマンドで、生成できます。

```bash
doxygen
```

## 作成されたドキュメントの一部

docs¥html配下にindex.htmlが作成されるので、それを参照してください。

こんな感じのドキュメントが生成されます。
シーケンス図がないので、処理の流れまでは分かりませんが、関連しているクラスまで
理解することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/e9bdc028-555f-c158-bffb-37f3f7af93c2.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/132118/f043cc77-2232-e96a-421a-7560f081a786.png)


# 終わりに
本当はシーケンス図までほしいのですが、さすがにそこまでは自動生成できませんした。
現状、シーケンス図も含めるためには、PlantUMLを使う方法があるようです。コメントにPlantUMLのDSLを書けばよいようなので、今度やってみようと思います。