コードリーディング-膨大なソースを解析するためのTips


既存プロジェクトにアサインした際によく「ソース or コード読んでおいて」といわれるのでコードリーディングについて自分なりにまとめてみました。だれかのお役に立てればと思います。

#この記事について

・大規模ソースを読むにあたり、どこから手をつけていいかわからないという人のためのガイドライン的なもの

# コードリーディングの目的

以下を理解し、アサインしたときや指示があったときに該当箇所の特定や追加作業がしやすくなる。

####1. コードのアルゴリズムを理解する

既存コードのプログラムの処理、流れ、手順を把握できる。

####2. データ構造を理解する

プログラム内で扱うデータ構造を理解することでデータの関係性や意味を把握できる。

####3. サービスロジックの把握

サービスの流れや処理について深めることができる。

# 準備編

####1.コードリーディング時の範囲の選定

「とりあえずすべてを理解しなくては」だと挫折するため、コードリーディングのスコープを決めて、あくまで必要な部分だけをコードリーディングするほうがよい。
コードリーディングはあくまで実装までの手段であることを忘れないでおく(コードリーディングが目的になってはいけない)。

####1.コードリーディング時の軸の選定

コードリーディングする範囲が決まったらコードリーディングする軸(どこから読んでいくか)を決める。
とりあえず、頭から読むだと効率が悪いので目的に応じて、軸を決めるとよい。

以下、例；
・APIならエンドポイントから処理を芋づる式に読む
・JavaScriptならユーザーアクションのトリガーから処理を芋づる式に読む
・Controllerからルーティング、アクションの流れで読むなど、、、etc

####2.仕様書や設計書があるなら絶対読む！！！！

過去の資産があるなら利用しない手はない。
該当部分の機能がなんのための機能なのか、コードを読みながら解いていくよりも仕様書、設計書を確認して、機能をおおまかなに把握しておくのとそうでないのとでは質もスピードも雲泥の差がある。
また、仕様書や設計書なしの把握しないままのリーディングは断片的な理解になりやすい。

####4.ファイル構造を理解する

OSSなフレームワークなどを利用しているのであれば、そのフレームワークのファイル構造やコンポーネント、利用しているライブラリなどを理解しておく。
独自のフレームワークなのであれば、そのフレームワークの設計書や有識者に確認する。
**※あくまでファイル構造を理解するのが目的なので主要な部分だけを理解するところでとどめておく、このタイミングでフレームワークやライブラリをすべてを理解する必要はない。**

####5.略語やプロジェクト独自のキーワードの調査

Googleなどで検索しても出てこない、プロジェクト独自のサービス用語や略語などのキーワードは有識者やドキュメントを見てあらかじめ、わかるものがあれば準備段階でMy用語辞典などを自分で作成しておく。
リーディング中にまたわからない独自のキーワードがでてきたら、確認してMy用語辞典などに追記していく。

# リーディング

リーディングをする前の準備が戦術、リーディング方法は戦術。

##リーディング方法

####●動的にコードリーディングする方法

デバッガなどを使って実行して、ログなどを確認しながら動きを追う方法。

####●静的にコードリーディングする方法

ソースコード自体を読んで動きを追う方法。

###理想的なコードリーディングの順番

できることなら、ソースコードを読むときの手順は以下が理想的。

```
動的にソースコードを追う方法　→　静的にソースコードを追う方法
```
静的にソースコードを追う方法はあくまで予想であり、対して、動的にソースコードを追う方法は事実となるため、プログラムの動きがわからない状況なら、まずは実際の動きの事実を見ておいたほうが、コードリーディングの質は上がり、スピードもあがる。

##リーディングツールの準備

####●タグジャンプツール

コードを読むにあたり、テキストエディタと基本コマンド(grep/find)では無理がある。

hoge()内でhoge2()を利用していて、hoge2()内の特定の変数を知りたいとなった場合、ファイルをまたいで関数から関数へジャンプしたり、戻ったりとなると無理がある。
なのでタグジャンプツール(ctagsなど)やタグジャンプツール同等の機能を持つIDEまたはテキストエディタを利用するのが望ましい。

####●Git

ソースコードがGitで管理されている前提。
コードリーディングする上では開発履歴となるGitは大いに役立つ。

#####コードリーディングに役立つ便利なGitコマンド

「git grep」gitで管理されているソースだけgrepするのに使える。

```
git grep "XXXX"
```

「git log」 gitのコミット履歴を閲覧できる。

```
git log {コミットID}
```

「git blame」 各行ごとに変更された最終コミットを知ることができる。

```
git blame {ファイル名}
```

##静的なコードリーディングのするときのポイント

###関連関数、関連クラスの各関係図を作成する

コードリーディングする際はデータの関係性を理解し、可視化するとコードリーディングする際に大いに役立つ。
また、頭の中で整理するのには限界があるのでクラスならクラス図、関数ならコールグラフを以下のような直感的にチャートを作成できるツールを用いるとよい。

[draw.io](https://app.diagrams.net/)　

また、コードでチャート作成ができる以下のようなツールがある。

[graphviz](https://www.graphviz.org/)

###関数の引数を調査する

関数だけでなく、引数も追跡して、どういうデータが引数にはいって、その引数がどういう流れで処理されていくかも追跡してみる。
また、動的にリーディングする際にはログなどで引数にどのような値が入るか確認。

###読まない技術

該当するコードを全部読むと時間もかかるし、大変なので本当に必要な箇所だけを読むためにも読まなくていい部分を読まない技術が必要。

こちらの記事がとても役に立ったのでおすすめ。

[コードリーディングの方法・コツ 読まない技術](https://qiita.com/miyagi1024/items/e47792be2204f4492258#%E8%AA%AD%E3%81%BE%E3%81%AA%E3%81%84%E6%8A%80%E8%A1%93)

以下、抜粋。

>・変数宣言は飛ばす
というか読み流す。
使われる時に確認するだけで良いです。

>・上の方で宣言されている関数は飛ばす
上の方で宣言されている関数は、下の方で宣言されている重要な関数のための部品である可能性が高いです。
なので、上の方で宣言されている関数ばっか読むのは時間の無駄になることが多いです。

>・長い関数の上の方の処理は飛ばす
長い関数の場合、一番下で呼ばれる関数一つのための準備が延々と書かれている、なんてザラにあります。
この場合は一番下で呼ばれる関数一つだけを読みましょう。

>・関数名から処理を推測
関数の名前は処理の要約です。
なので、その名前から内部の処理が推測できれば、中身のコードを読む必要はありません。
ただし、関数名が嘘を言っている可能性もあるので注意してください。
「一度決めたら後から改名できなくなってしまったので名前を変えずに処理を追加した」など、かなり有名なプロジェクトでもわりと多くの頻度で嘘があります。
関数名から関数の処理を推測できない場合かもしくは推測が間違ってそうな場合はちゃんと中身のコードを読みましょう。
この時一番注意しなければならないことは「重要そうではない関数名の関数が重要な処理をしている」という場合が存在することです。

>・例外処理は飛ばす
例外処理は読む必要ありません。
飛ばしてしまいましょう。
例外処理を例外処理だと気付く技術がとても重要になります。
条件分岐がでてきたら例外処理か否かを一度考える癖をつけておきましょう。
また、例外処理は、大体上の方にあります。
特にelseなどがある場合の上位のifには注意してください。

>・Switch文は簡単そうな一つを選んで読んでみる
Switch文でたくさんのcaseがある場合では、まず上から読むというのは悪手です。
たくさんのcaseの中から一番簡単そうなものを選び、そこだけを読んで全体のswitchの意味合いを推測します。

##参考文献

[大規模ソースコードの読み方](https://www.slideshare.net/satorutakeuchi18/viewing-source-code)

[ソースコードの追い方、読み方の方法やコツをまとめておく](https://boukenki.info/sorce-code-oikata-yomikata-houhou-kotu-matome/#i-4)

[複数人での Git 開発に便利な 3 つのコマンド](https://qiita.com/rosylilly/items/9648ad2c8aa53465372b)

[Git の便利コマンド色々 〜ソースコードリーディング編〜](http://kotak.hatenablog.com/entry/20100319/p1)

[コードリーディングの方法・コツ](https://qiita.com/miyagi1024/items/e47792be2204f4492258)