- 本書における「設計」の定義
- 用語についての注意
- 設計の本質は「責任の分割」
- 責任を分けただけでは、設計は完成しない
- 構造による保証とは何か
- 設計とアーキテクチャの違い
- 設計の8割は、構造で決まる
- 良い設計は、壊そうと思っても壊せない
- 良い設計は、変更の影響が爆発しない
- 良い設計は、人間の思考コストを下げる
- 良い設計は、属人化しない
- 設計に正解はないが、説明は必要
- この章のまとめ
多くのエンジニアは、 「設計」という言葉を使いながら、 実は同じものを指していません。
ある人は、 クラス図やレイヤー構成のことを指します。
ある人は、 アーキテクチャやフレームワーク選定を指します。
またある人は、 実装前に少し考えること自体を、 設計と呼んでいるかもしれません。
本書では、 まずこの曖昧さを取り除きます。
本書における「設計」の定義
本書では、設計を次のように定義します。
設計とは、
責任を分割し、その正しさを構造によって保証すること です。
これを、式で表すとこうなります。
責任の分割 + 構造による保証 = 設計
この式が、 本書全体を通しての軸になります。
用語についての注意
本書では、 構造による保証 を表現する際に、 文脈に応じて、
- 制約
- 制限
- 保証
- 強制
- 誘導
といった言葉を使います。
しかし、指している本質は一つです。
それは、
やってはいけないことを、人が判断するのではなく、 構造によって、そもそもできなくする
という考え方です。 (これらの言葉は、あくまで、文脈によって使い分けるだけです。)
設計の本質は「責任の分割」
まず、設計の目的から見ていきます。
設計の本質は、責任の分割 です。
ここで言う責任とは、 わかりやすく言えば、
クラスや関数が持つ役割
のことです。
- 何を知っているのか
- 何を知らなくてよいのか
- 何の役割を担うのか
これらを明確に分けることが、 設計の出発点です。
責任が曖昧なまま集まっている構造は、 どれだけ読みやすく書かれていても、 壊れやすい設計になります。
責任を分けただけでは、設計は完成しない
責任を分割することは重要です。
しかし、それだけでは不十分です。
なぜなら、 分割された責任が、
- 守られるかどうか
- 正しく使われるかどうか
が、人の注意に委ねられてしまうからです。
ここで必要になるのが、 構造による保証 です。
構造による保証とは何か
構造による保証とは、
やっていいこと / いけないことを、 人が判断するのではなく、 プログラミング言語の制約によって実現すること
です。
たとえば、
必ずこの順番で呼ばなければならない → そもそも順番を間違えて呼べない API にする
null を渡してはいけない → null を表現できない型にする
特定の条件下でしか使えない → その条件を満たした状態でしか生成できないオブジェクトにする
こうした工夫は、
- 「ここは気をつけて使ってください」
- 「ドキュメントを読めばわかります」
といった、 人に依存したルールとは本質的に異なります。
設計とアーキテクチャの違い
設計とアーキテクチャは、 別物として語られることがあります。
しかし本質的には、
設計とアーキテクチャの違いは、スコープの違い です。
- 一つの関数やクラスの責任をどう分けるか
- モジュール間の責任をどう分けるか
- アプリ全体の責任をどう分けるか
どのレベルであっても、
責任を分割し、 それを構造によって保証する
という問いに答えている点は同じです。
設計の8割は、構造で決まる
設計というと、 「どう書くか」「どう実装するか」 に意識が向きがちです。
しかし実際には、
設計の8割は、構造で決まります。
構造とは、
- 何ができて、何ができないか
- どこまで知ってよいか
- どこから先は触れないか
といった、 選択肢そのものを制限する枠組みです。
この枠組みが、 人の注意ではなく、 構造によって守られているかどうか。
そこに、 設計の良し悪しが現れます。
良い設計は、壊そうと思っても壊せない
本書が考える良い設計は、
壊そうと思っても壊せない構造 を持っています。
これは、 バグが一切出ないという意味ではありません。
- 間違った使い方をしようとすると書けない
- 書こうとすると、すぐに違和感が出る
- 変更すると、影響範囲が自然に限定される
こうした状態は、
正しさが、構造によって保証されている から生まれます。
良い設計は、変更の影響が爆発しない
設計の良し悪しが最も表れるのは、 変更が入ったときです。
責任が分割され、 構造によって保証されている設計では、
- 変更理由が一つに定まり
- 修正箇所が自然に絞られ
- 他の部分を疑わなくて済む
という状態になります。
これは、コードを修正した人が優秀だからではありません。
構造が、変更を制御している からです。
良い設計は、人間の思考コストを下げる
良い設計がされたコードは、 読んでいて楽です。
それは、 人が毎回判断しなくてよいからです。
- これは考えなくてよい
- ここは迷わなくてよい
- これは構造が保証している
良い設計は、 人に頑張らせません。
構造に仕事をさせます。
良い設計は、属人化しない
属人化は、 人の問題だと思われがちです。
しかし本書では、
属人化は、 正しさが構造で保証されていない設計の結果 だと考えます。
特定の人だけが正しさを知っている状態は、 責任がコードではなく、 人に乗っている状態です。
良い設計では、
- 判断は構造にあり
- 人はそれに従うだけでよく
- 後から来た人でも安全に触れる
という状態になります。
設計に正解はないが、説明は必要
設計に、 唯一の正解はありません。
ただし、
説明できない設計は、 責任の分割や保証の意図が曖昧な可能性があります。
なぜこの構造なのか。 なぜこの責任の分け方なのか。
それを言語化できる設計は、 構造として優れています。
この章のまとめ
設計とは、
責任の分割 + 構造による保証
です。
責任は、 人が意識して守るものではありません。
構造によって、保証されるべきもの です。
次の章では、 この「保証」が失われたとき、 コードの中で何が起きるのか。
「判断」という切り口から、 さらに掘り下げていきます。