読書要点「プリンシプルオブプログラミング」第3章 プログラミングセオリー


第3章 思想

プログラミングを支えてきた思想である。
今まで多くのソフトウェアの成功を支えてきた思想を、身近に活かすことのできる場面は少なくない。

プログラミングセオリー

プログラミング最大の関心事は最高のコードを作り上げることである。
最高のコードとは、拡張しやすく、余計なものがない、読解しやすいコードである。
最高のコードを実現するためのセオリーがプログラミングにはある。

セオリーを支える根幹の価値は3つある。
それはコミュニケーション、シンプル、柔軟性である。
また、この抽象的な価値を実務に適用していくための原則が6つ存在している。
結果の局所化、対称性、繰り返しの最小化、宣言型の表現、ロジックとデータの一体化、変更頻度である。

以降、この価値と原則について個別に説明していく。

価値:コミュニケーション

コードは人が読むドキュメントであり、コミュニケーションツールの一つであると言える。
コードを書く時間以上に読む時間が長くなる開発の中で、円滑なコミュニケーションを行うために読みやすいコードを書くことはとても重要である。
書いているときほど読み手側の視点に立って考えるべきである。

価値:シンプル

ここでいうシンプルとは、コードに含まれる余分な複雑性を排除した状態のことである。
要件を満たすために必要な複雑性ではなく、過剰な遠回りをしているような複雑性のことである。
読み手側は読むコードが簡潔なほど理解に要する時間は短くなり、保守も行いやすくなる。

まれにシンプルとコミュニケーションが競合する場合があるが、その場合はコミュニケーションを優先するべきである。
長期的に読まれていくことを考えると、読み手と円滑なコミュニケーションを行うことのほうが優先度が高い。

価値:柔軟性

ここで言う柔軟性とは、コードの変更が容易であるということだ。
いずれコードが変更され、長期的に保守が行われることを考えるとコードは柔軟性を持っているに越したことはない。

ただし、柔軟性を理由にコードが複雑性を持つことを正当化されがちである。
ここで、現在必要ではないものは書かないYAGNIという原則を思い出したい。
今必要のないものは結果として複雑性を増すのみだという認識を持ち、真に保守性の高いコードを書くことを心がけたい。

原則:結果の局所化

ここでいう結果とは、コードを変更したときの影響のことを言う。
結果の局所化とは、変更の影響が局所的に留まるようにすべきだという原則である。
モジュール化やMVCモデルをはじめ多くの技術が、結果の局所化の実現を目指して生み出された。

結果が局所化されているほど、保守の際のコストが減るうえ、局所化がされているという共通認識があればコミュニケーションのコストも抑えることができる。

関係が濃密なコードをひとまとめにして、過剰に分散させないことが重要だ。

原則:繰り返しの最小化

ここでいう繰り返しとは重複のことであり、重複はできるだけ減らしたほうが良いという原則である。
関数化のような技術は繰り返しの最小化を動機としている。
コピペを複数ヶ所に含むコードは結果の局所化の減速を侵害しており、変更コストが大きい。
また、似たような記述から変更すべきか否かを判断することになり、読むコストも増える。

同じ記述を減らすためにもコードを小さい単位に分割して管理するのが良い。
分割していく過程でコードが持つ共通項の把握も進む。

原則:ロジックとデータの一体化

処理と処理で扱うデータをなるべく近くに配置すべきだという原則である。
コードの修正する時、処理とデータを変更するタイミングはだいたい同じである。
変更するタイミングが同じものは近くにあったほうが読むコストが減るうえに、結果の局所化にもつながる。

原則:対称性

コードの中のグループにおいて、同じ種類のものを同じレベルで表現すべきだという原則である。
コードの対称性は可読性を引き上げる。
一部を読むだけでグループが持つ性質、グループの他の部分への類推が可能になる。

原則:宣言型の表現

宣言型の表現と命令型の表現の2種類がある。
宣言型では問題の定義を記述し、命令型では問題の解法を記述する。
宣言型では順序や条件分岐がなく論理的な流れは存在しないためコードを読みやすい。

積極的に宣言型のコードを取り入れ、読みやすいコードを作るのが良い。
命令型のプログラミング言語でも宣言型の記法が用意されていたり、宣言型の考えを取り入れたフレームワークがあるため、宣言型の言語と合わせて取り入れていきたい。

原則:変更頻度

コードのグルーピングの際に、コードの変更頻度で分類すると良いということである。

「対称性」では同種のものをグループ化することを推奨したが、こちらでは時間軸的に考えてグループ化を行う。
同じタイミングで変更するコードをまとめておけば、コードの修正範囲は狭くなり、結果の局所化につながる。
また、そもそも変更頻度が同じものは変更の理由も同じことが多い。

モジュールを作るときは、モジュールが持つ責任は一つより多くあってはいけないという単一責任の減速を意識しておくと、変更頻度の原則の達成につながる。