※ こちらは別アカウントで2025年7月8日に公開していたものをアカウント統合のため移植したものです。
はじめに
今更ながら『プリンシプル オブ プログラミング 3年目までに身につけたい一生役立つ101の原理原則』を読んでみました。
そしてようやく重い腰を上げて初アウトプットです。どっこいしょ。
標題の件の通りですが、DRYやらSOLIDやらその他にもいろいろ、プログラミングの原理原則はたくさんありますよね。
それらを個別で学んでしまったのでイマイチ記憶の定着がよくないなあ、どれもうろ覚えになっているなあと個人的には感じています。
プログラミングの原理原則はなんのためにあるのか、体系的にそれらを理解することはできないかと思い、手に取ったのが「プリンシプルオブプログラミング」でした。
101もの原理原則を取り上げているので、共通項を抽出したり、グルーピングしたりすれば、より理解が進みそうだと考えた次第です。
本来は全て読み終えてからまとめたかったのですが、第3章を読んでいて、なかなかすんなりとは理解しにくくなってきたと感じたので、いったん第2章までで自分なりに整理してみて、その上で先を読み進めようと思います。
おさらい
簡単に第2章までの内容についておさらいしていきます。
本書は数多くのプリンシプルを取り上げるにあたって、当然ながら理解しやすいよう、読みやすいような構成になっています。
まだ第3章の途中までしか読んでいない身ではありますが、普遍的なものからより具体の話に移ろっていくストーリーになっています。
第1章 前提 ~ プログラミングの変わらぬ事実 ~
タイトルの通りですが、第1章はソフトウェアやプログラミングの純然たる事実について記されています。
これらは次章以降で取り上げるプリンシプルの前提知識になるものです。
内容を要約すると以下のとおりです。
- ソフトウェアは困難である
- コード = 設計書
- コードは必ず変更される
第2章 原則 ~ プログラミングのガイドライン ~
第2章はプリンシプルの中でも原則、より基本的なきまりごとについて取り扱っています。
取り上げるプリンシプルも聞いたことがあるものばかりで理解しやすいです。
- KISS (Keep It Simple, Stupid)
- DRY (Don't Repeat Yourself)
- YAGNI (You Aren't Going to Need It)
- PIE (Program Intently and Expressively)
- SLAP (Single Level Of Abstraction Principle)
- OCP (Open-Closed Principle)
- 名前重要
個人的に以下はプリンシプル名だけでは理解しにくいと感じたので補足します。
PIEとは意図を表現してプログラミングせよ、という意味です。
これはソースコードは誰かが読むことを想定しているためにソフトウェアの動作を完全に正確に知ることができるようにしておく必要があるということです。
OCPとは、コードの振る舞いを拡張でき(Open)、かつコードの振る舞いを拡張しても、その他のコードは全く影響を受けない(Close)という意味です。
困難性と拡張性
これまでに見てきた、特に第2章のプリンシプルをどうしたら体系的に扱えるかを考えてみたのですが、目的としてはソフトウェアの困難性と拡張性に立ち向かうためであり、困難性と拡張性のどちらに親和的かで分類(両方にかかるものもある)できそうかなと感じました。
困難性のところは複雑性と安直に書きたかったのですが、本書では困難性の一要素として複雑性について記述している箇所があったため、本書に倣い、意識的に困難性を使います。
また、現状第2章のプリンシプルを見る限りでは困難性だけでも良さそうかとも思ったのですが、よくプログラミングと似て非なるものとして話に上がる建築との違いは何かという点でいうと「完成した後も手を入れ続ける」というのがあり、また、第1章でも「コードは必ず変更される」とあり、拡張性こそがソフトウェア及びプログラミングの最重要事項だと思ったので入れています。
もうお気づきの人もいるでしょうが、第1章の前提がほぼ反映されていますね。
「コード = 設計書」については拾えてませんが、これは私の理解が足りておらず、重要度に気づけていないのだと思います。今後読み進めていくにつれて何かしら分かるのではないかと期待しています。
困難性とは
また建築の話を持ち出すのですが、建物の場合、視認で構成要素を把握できますし、その組み方だと物理法則的にまずいなとか、このまま上に何かを積めば耐えきれず壊れるなとかが分かりやすいのではないかと思います。
一方でプログラミングの場合、なにがどこに紐づいているかぱっと見では分かりません。
仮に読みにくい、分かりにくいコードがあったとして、自分のスキル不足で理解できないだけということもなくはないでしょうし、問題があったとしても、それがなんの法則に反していてどんな危険性を孕んでいるのか、正確に把握するのは難しいです。
本書で取り上げる最初のプリンシプルでは、「ソフトウェアは本質的に困難である」と述べ、困難の内訳として「複雑性」「同調性」「可変性」「不可視性」の四つの要素を上げています。
- 複雑性
- コード数や構成要素の依存関係など、ソフトウェアはそのものが大きくて複雑である
- 同調性
- ソフトウェアは複雑な実世界に同調する必要がある
- 可変性
- ソフトウェアは完成後も変化し続ける
- 不可視性
- ソフトウェアは概念の集積であり目に見えない
建築との比較話は、私が思う困難性について述べたものですが、特に不可視性を意識してそうですね。
実際、複雑性の四つの要素の中で個人的に厄介だと思うのは不可視性かなと感じます。
拡張性とは
先にも述べましたが、完成したら基本はそれで終わりの建築とは違い、機能の追加やリファクタリングなどで改修し続けるのがシステムの特性だと思います。
本書の三つめのプリンシプルとして「コードは必ず変更される」が取り上げられています。
このプリンシプルはわりとあっさりまとめてあり、「変更に強いコードを書く」と締め括られてますが、変更に強いコードとは何か考えてみました。
早速ですが、観点としては拡張できるかどうかと拡張可否を判断できるかどうか、の二つがあると考えました。
詳しく述べると以下のとおりです。
- 物理的に(厳密には論理的に?)変更できる、変更しやすい状態になっているか
- システムの全容と詳細を理解しやすい状態になっているか
前者は簡素なシステム構造とか、後者は読みやすいコードとかになるでしょうか。
こうみると複雑性と被る部分が大きいですね。
でもやはり拡張性がシステムの重要な特性だと思うので、一旦は別物として考えて見たいと思います。
プリンシプルの整理
困難性と拡張性のふたつの観点から第二章のプリンシプルを整理してみました。
いずれのプリンシプルも困難性および拡張性のどちらとも被るとは思いつつ、よりどちらを意識してそうかで分類しています。
また、抽象と具体の関係を矢印で表現しています。
KISSは簡潔にしろという意味なので単に困難性の部分にかかってくると捉えました。
DRYやYAGNIは簡潔にする中でも、具体として無駄なものを書くなという意味合いでやはり困難性に親和的な要素でしょう。
DRYについては気をつける背景としてコードが改善できなくなるとあったので拡張性の方に少し寄せました。
PIEはコードの読みやすさを意識したものなので拡張性の方に置きました。
SLAPについては抽象度を揃えるということでシステムの構造をシンプルにする意味合いもありそうだなと思いつつも、コードの要約性や閲覧性について述べられていたので、拡張性寄りにしています。
OCPは拡張に対して開いている、修正に対して閉じているという意味合いなので、拡張性そのものの話です。
最後に名前重要ですが、これは読み手がいるからこその話なのでPIE同様拡張性に属する要素でしょう。
図示してみて改めて気づきましたが、困難性は簡潔、拡張性は意図あたりがキーワードになりそうですね。(拡張性はOCPがうまく組み込めてませんが...ぐぬぬ...なにか良いワードはあるだろうか...)
さいごに
自分なりに整理することでたんにプリンシプルをひとつずつ拾い集めるだけでは見えなかったものが見えるようになったのではないかと思います。
これはあくまで私なりの整理の結果なので他の人はまた違った解釈をするかもしれません。
プリンシプルオブプログラミングは著名な書籍なのでいろんなレビュー記事があると思いますが、今回執筆するに当たっては引っ張られないように敢えて読みませんでした。
第3章以降は読み進めている途中なので、まだ他のレビュー記事は読まないでおこうと思いますが、また思うことがあれば執筆したいと思ってますし、読了した暁にはレビュー記事を読むつもりなので、学べることがたくさんありそうでわくわくしています。
