プログラマーの教養としての原則
参考
プリンシプル オブ プログラミング - 3年目までに身につけたい一生役立つ101の原理原則
発行: 2016/3/23
著者: 上田 勲
まえがき
プログラマーの世界で語り継がれる原則や格言を知ることは、その共通の言語や道徳を理解する手助けとなります。
『プリンシプル オブ プログラミング』(以下、プリプロ)は、統一された語句と形式により、先人のプログラマーたちが重要視していた思考法やアプローチを、微妙な概念の違いに気を使うことなく理解できるよう構築されています。この記事では、この本を読む上で役立つ101の原則マップと原則から抽出した価値観をまとめます。プリプロを読む際のガイドになればと思います。
一方で、プリプロに収録されていないウィットに富んだ原則や格言も多く存在します。この記事では、主に私の現場で重要視しているプリプロの101の原則以外の原則・格言も追加で紹介します。
プログラマーにとって善いとされる価値観を共有できれば嬉しいです。
101の原則マップ
目次を図にしてみました。これを手に取りながらプリプロを読むことで、全体像が俯瞰でき原則間の関係性が把握しやすくなるかと思います。
101の原則から抽出した価値観
プリプロに散りばめられた原則をギュッと抽出しました。経験豊富なプログラマーが直感的に選択している核となる価値観を明文化できたように思います。
核となる5視点・指針
プログラミングの原則の核となる大きく5つの視点とその指針を以下のようにまとめました。
- コミュニケーション: 背景を伝えるコードと、コードを伝えるための仕組みと文化を
- コード: 基本はシンプルに、拡張・保守・堅牢さによる複雑さは狙って
- 活動: 小さなステップで、継続的に、重要なことから確実に
- 決断: 選択肢をグラデーションで捉え、ユーザの視点で
- 命名: 名前重要、対称性を意識し、適切な抽象度で
優先事項
プログラミングやコードレビューを行う際には、以下の優先順位で考慮することが望ましいです。
- コミュニケーション
- シンプル
- 保守性
- 堅牢性
- 拡張性
- パフォーマンス
プログラミングやコードレビューのタイミングでは、主に1~3の項目に重点を置くことが望ましいです。堅牢性、拡張性、パフォーマンスについては、個別に計画と設計を行うべきで、思いつきで調整をしません。
101の原則以外の原則・格言
プリプロにない原則や格言をまとめました。これらは直接的には書かれていませんが、重なる部分もあります。私が独断と偏見で選んだ、現場や教育で大切にしている好きな原則や格言です。できるだけプリプロにならい言葉を統一しています。
シンプルすぎてもいけない
シンプルにすることで分かりづらくなることがあります。
"It can scarcely be denied that the supreme goal of all theory is to make the irreducible basic elements as simple and as few as possible without having to surrender the adequate representation of a single datum of experience."
─── Albert Einstein (1933) On the Method of Theoretical Physics
アインシュタインは理論構築において、可能な限りシンプルで、しかし正確に表現できるようなバランスが重要であることを強調しています。彼の業績からもこれを意識して実践していたことがわかります。
"Everything should be made as simple as possible, but not simpler"
『On the Method of Theoretical Physics』の一節はしばし、このように引用されます。汎用的な表現になっていて使いやすい格言です。
シンプルだけを目指してDRY(Don't Repeat Yourself)にするよりも、関係性やコンテキストから高凝集になるようプログラミングする方がコードは扱いやすくなります。もっと簡単に言えば「シンプルにしたことで分かりやすくなっていること」を意識すべきです。
語彙は思考の幅
"Don't you see that the whole aim of Newspeak is to narrow the range of thought? In the end we shall make thoughtcrime literally impossible, because there will be no words in which to express it."
─── George Orwell (1949) 1984
ジョージ・オーウェルのディストピアSF小説『1984』からの一節。Newspeakとは小説に登場する、語彙を制限し思考を支配するために生まれた架空の言語のことです。ジョシュア・ツリーの法則やフランシス・ベーコンの市場のイドラのように、人間は言葉を知らなければ世界を理解することができず、誤った判断をしてしまう可能性があることを示唆しています。
チームで使われている言葉にこだわる必要があります。使用されている語彙を辞書にして、誰でも閲覧可能にし、それをユーザが触れられる所からコードまで統一する、ユビキタス言語のようなアンチNewspeakな取り組みは、思考を整理しコミュニケーションを円滑にします。
また私の経験的に使用しているプログラミング言語もまた、思考へ影響する側面がありそうです。プログラミング言語によってコミュニティの雰囲気が違うのはなかなか面白い事象です。複数のプログラミング言語を学ぶことは、スキル向上だけでなく、その言語の機能や特徴を相対的に理解する意味でも価値があります。
"Dans la langue il n'y a que des différences."
─── Ferdinand de Saussure (1916) Cours de linguistique générale
これは言語学者ソシュールの言葉で「言語には差異しかない」と訳されます。言葉とは物事を区別するためにあるということ。
プログラマーは原則・格言を始めとしてトレンドのリポジトリ、ライブラリのリファレンスなどから語彙を構築します。言葉を知らなければ違いを識別できず、想像、意見、抽象化/具体化といったことが制限されてしまいます。プログラミングは言葉の創造の連続です。プログラマーは違いが明確に伝わる言葉選びに魅了されます。
ソフトウェアを作るとは切り分けること
"え?ソフトウェアを作るって、どんな仕事かわからない?
『切り分け』"
─── 友達
私が度肝を抜かれた言葉です。ソフトウェア開発における「切り分け」というのは、つまり以下のことを指しています。
- 言葉で概念を使い分けること
- if文で場合分けすること
- 現状と目的の差分を見ること
バス係数
"Bus factor (noun): the number of people that need to get hit by a bus before your project is completely doomed."
─── Brian W. Fitzpatrick (2012) Team Geek: A Software Developer's Guide to Working Well With Others
バス係数は「プロジェクトが壊滅するまで何人バスに轢かれることができるかを示す指数」のことです。人は突然にいなくなります。これを念頭に置き、コードの記述およびナレッジマネージメントをし、作業が誰でも再現可能にできる様に意識を払います。特に再現するのが難しい「トッププログラマーがどうしてその選択をしたのか」が記録されるようにします。
"旅団ではオレが頭でお前達は手足、手足は頭の指令に対して忠実に動くのが大原則だ。それは機能としての話で生死の話ではない。例えば頭が死んでも誰かが跡を継げばいい、場合によっては頭より足の方が大事な時もあるだろう。"
─── 冨樫 義博 (2001) HUNTER×HUNTER 12巻
こちらはハンターハンターのクロロの格言。かっこよくバス係数を語りたいときはこれです。
現場猫のオアシス
"「お」れじゃない、「あ」いつがやった、「し」らない、「す」んだこと"
─── ネットミーム
アンチパターン。あるいは地獄。失敗は当人を攻めるのではなく、それに至った環境や背景に目を向けて解決していきます。地獄とは環境です。
-
チーム内で人格攻撃があり、自己防衛的でないか?
- 根本的な帰属の誤り: "状況的な要因を過小評価し、当人の性格に焦点をあてすぎてしまう認知バイアス"を疑う
-
チーム内は威圧的な雰囲気で、個人が自分の意見を述べにくい状況でないか?
- ミルグラム実験: "閉鎖的な状況における権威者の指示に従う人間の認知特性"を疑う
- 心理的安全性: "対人関係においてリスクある行動をとったとしても、チーム内が安全であるという気持ちがメンバー内で共有された状態"にする
コードレビューにこだわる
コードレビューはきれいなコードを維持する要です。以下は、コードレビューにこだわるために知っておきたい資料です。
- コードレビューのベストプラクティス - Best practices for pull requests
- レビューする側としての立ち回り - Code Health: Respectful Reviews == Useful Reviews
- ユニットテストの考え方 - Shift testing left with unit tests
コードレビューはコミュニケーションです。これをより有意義にするためには、コードを書いたプログラマーが積極的にチームに情報を共有することが必要です。コードレビューの直前は、プログラマーが対象の要件について一番詳しいのです。チームに伝わる環境を整えるために、コードレビューの前に自己レビューとして以下を実施します。
- 原則・チームのルールに沿っているかの確認
- ユニットテストの作成
- 静的解析の実施
- LLM解析の実施
- 背景がわかるようにする(たとえばWork Itemをリンクする)
- 懸念点や妥協点を示す
セキュリティは主役じゃない
"セキュリティ製品は、ユーザーの“本当にやりたい作業”を邪魔してはいけない"
─── Richard Marko (2013) 「セキュリティはユーザーの邪魔をするな」一徹なESETの25年
私の好きな言葉です。プリプロではセキュリティ強度と利便性として言及がありました。当然、セキュリティの考慮は確実に必要です。しかし影の立役者に徹するべきです。
阿部寛のホームページ
"ソフトウェアは、ハードウェアが高速化するより急速に低速化する"
─── ヴィルトの法則
高い汎用性を持つアーキテクチャやプログラミング言語を採用することで、開発速度の向上や手軽にリッチな描画が可能になりましたが、その代償としてハードウェアコストが増加しました。
しかしそのような昨今、燦然と輝くのは阿部寛のホームページです。ユーザが求めているものとはなにか、本当に大切なことを考えさせられます。
ポステルの法則
"Be conservative in what you do, be liberal in what you accept from others."
─── Postel's Law
ロバストネス原則とも呼ばれるこの法則は、インターネットのプロトコル設計者であるジョン・ポステルによるものです。寛容にしたい受け入れ側に意図的に複雑さを取り込みます。私はデバイスドライバーの開発において、この法則を適用することで安定性を確保できました。
この法則についてプリプロでも言及されていましたが、名称は載っていませんでした。名前があることによって、意識しやすく、コミュニケーションで利用しやすくなりますので掲載してみた次第です。
Hands-on Modelers
"Any technical person contributing to the model must spend some time touching the code, whatever primary role he or she plays on the project. Anyone responsible for changing code must learn to express a model through the code. "
─── Evans Eric (2015) Domain-Driven Design Reference
設計する人はコードにも触れる。逆もまた然り。コードを書くことを設計と位置づけたとしても、理論を説明するスキルとプログラミングのスキルは異なるため「両方やってやるぞ」という意気込みは重要です。それがソフトウェアの理解や素早い問題解決に繋がります。
誰もがHands-on Modelersであるかどうかで組織づくりも変わってきます。プロセスで組織化するのではなく、要件の関係性を凝縮するような組織の方が柔軟な対応が可能です。
設計のスイートスポット
使える時間は有限です。設計に時間をかけすぎてもいけないし、ただやみくもに作ってもアーキテクチャが浮かび上がって来ることはなさそうです。
"ソフトウェアシステムの大きさと要求の多様性に応じて、全てのソフトウェアシステムにはデザインスイートスポットを持っている。それは、実装に入る前にアーキテクチャ設計に費やすのに最適な時間のことだ。"
─── Design It! プログラマーのためのアーキテクティング入門 (2019) マイケル・キーリング, 島田 浩二
複雑さを取り込む時、それに取り組むための設計のスイートスポットを見つけるように努めます。設計活動はどうしても、やりすぎてしまうか、全くやらないかの両極端になりがちです。対象の複雑さやコンテクストに応じて「いい感じになるまで設計する」と考えるだけでも時間や品質のバランスがとれそうです。
"先読みしすぎた設計BDUF(Big Design Up Front)はよくないにしてもNDUF(No Design Up Front)はあまりにもリスクが高い。私たちは、EDUF(Enough Design Up Front)を目指している(一部編集)"
─── Design It! プログラマーのためのアーキテクティング入門 (2019) マイケル・キーリング, 島田 浩二
ウォーターフォール、アジャイル、その先にEDUFはあります。EDUFを目指し、プロジェクトの初期段階から継続的に十分な設計活動を行うことで、最適なコストで変化に柔軟に対応できるアーキテクチャが構築できます。
Copilot
LLMを使うMicrosoftの製品にCopilotという名称が付けられています。Copilotという命名から、意思決定のサポート役であることがふつふつと伝わってきます。
LLMを使って仕事するのが当たり前になったように感じます。LLMによって便利になる一方、悲しいことにコピペマンがより巧妙になったことも事実です。だからこそ、「AIはCopilot」「最後は自分で決める」という自己の意識づけ・リテラシーが重要に感じます。
LLMの利用の基本を抽象化し「入力を適切に与え、出力を適切に評価する」とすると、人に何か頼むときと何ら変わらないし、もっと言えば関数を使う時に意識することと同じです。プログラマーは初めからCopilotが得意なのかもしれないです。
原則原理主義に陥らない
言葉を知ることで自由に思考できるようになる一方、言葉に囚われて不自由になってしまうことがあります。
善いプログラミングをするための原則という手段は、時折それを守ることが目的になってしまいます。言葉を大切にすることは良いことですが、言葉は差異を生み出すものであり、すがるものではありません。
すでに共通言語になっている言葉に、真なる意味を見出すまではいいのですが、押し付けるのはよくありません。おそらく、多くの人が誤解したまま共通となった言葉には、新たな言葉が必要なのだと思います。言葉もリファクタリングしていく必要がありそうです。
原則を体験に活かす
プリプロには「3年目までに身につけたい一生役立つ101の原理原則」という副題があります。3年目までにプログラマーの世界の原則・格言を知り共通言語を身につけることで、ソフトウェア開発活動においてコミュニケーションが捗ることと思います。
また、原則・格言には他者の経験を学べるという側面もあります。
"Men are wise in proportion, not to their experience, but to their capacity for experience."
─── George Bernard Shaw
これはプリプロにも書かれている文学者のジョージ・バーナード・ショーの格言とされている一節です。他者の経験から学び、そして体験を通して成長する。その体験から原則を再確認したり再定義したりする姿勢が、プログラマーに求められる教養なのかなと思います。
おわりに
原則や格言を知り、先人の考えた概念に思いを馳せることは、プログラマーが概念や事象を切り分けるための教養です。言葉を知ることで、より良い体験をするための足がかりとなり、チームのコミュニケーションの促進にもつながります。
プログラマーの教養としての原則とは、新たな技術や手法が激しく変化する世界の中でも存在し続ける、しなやかで大切な言葉です。
Discussion