多くのエンジニアは、 「設計」という言葉を使いながら、 実は同じものを指していません。

ある人は、 クラス図やレイヤー構成のことを指します。

ある人は、 アーキテクチャやフレームワーク選定を指します。

またある人は、 実装前に少し考えること自体を、 設計と呼んでいるかもしれません。

本書では、 まずこの曖昧さを取り除きます。


本書における「設計」の定義

本書では、設計を次のように定義します。

設計とは、

責任を分割し、その正しさを構造によって保証すること です。

これを、式で表すとこうなります。

責任の分割 + 構造による保証 = 設計

この式が、 本書全体を通しての軸になります。


用語についての注意

本書では、 構造による保証 を表現する際に、 文脈に応じて、

  • 制約
  • 制限
  • 保証
  • 強制
  • 誘導

といった言葉を使います。

しかし、指している本質は一つです。

それは、

やってはいけないことを、人が判断するのではなく、 構造によって、そもそもできなくする

という考え方です。 (これらの言葉は、あくまで、文脈によって使い分けるだけです。)


設計の本質は「責任の分割」

まず、設計の目的から見ていきます。

設計の本質は、責任の分割 です。

ここで言う責任とは、 わかりやすく言えば、

クラスや関数が持つ役割

のことです。

  • 何を知っているのか
  • 何を知らなくてよいのか
  • 何の役割を担うのか

これらを明確に分けることが、 設計の出発点です。

責任が曖昧なまま集まっている構造は、 どれだけ読みやすく書かれていても、 壊れやすい設計になります。


責任を分けただけでは、設計は完成しない

責任を分割することは重要です。

しかし、それだけでは不十分です。

なぜなら、 分割された責任が、

  • 守られるかどうか
  • 正しく使われるかどうか

が、人の注意に委ねられてしまうからです。

ここで必要になるのが、 構造による保証 です。


構造による保証とは何か

構造による保証とは、

やっていいこと / いけないことを、 人が判断するのではなく、 プログラミング言語の制約によって実現すること

です。

たとえば、

  • 必ずこの順番で呼ばなければならない → そもそも順番を間違えて呼べない API にする

  • null を渡してはいけない → null を表現できない型にする

  • 特定の条件下でしか使えない → その条件を満たした状態でしか生成できないオブジェクトにする

こうした工夫は、

  • 「ここは気をつけて使ってください」
  • 「ドキュメントを読めばわかります」

といった、 人に依存したルールとは本質的に異なります。


設計とアーキテクチャの違い

設計とアーキテクチャは、 別物として語られることがあります。

しかし本質的には、

設計とアーキテクチャの違いは、スコープの違い です。

  • 一つの関数やクラスの責任をどう分けるか
  • モジュール間の責任をどう分けるか
  • アプリ全体の責任をどう分けるか

どのレベルであっても、

責任を分割し、 それを構造によって保証する

という問いに答えている点は同じです。


設計の8割は、構造で決まる

設計というと、 「どう書くか」「どう実装するか」 に意識が向きがちです。

しかし実際には、

設計の8割は、構造で決まります。

構造とは、

  • 何ができて、何ができないか
  • どこまで知ってよいか
  • どこから先は触れないか

といった、 選択肢そのものを制限する枠組みです。

この枠組みが、 人の注意ではなく、 構造によって守られているかどうか。

そこに、 設計の良し悪しが現れます。


良い設計は、壊そうと思っても壊せない

本書が考える良い設計は、

壊そうと思っても壊せない構造 を持っています。

これは、 バグが一切出ないという意味ではありません。

  • 間違った使い方をしようとすると書けない
  • 書こうとすると、すぐに違和感が出る
  • 変更すると、影響範囲が自然に限定される

こうした状態は、

正しさが、構造によって保証されている から生まれます。


良い設計は、変更の影響が爆発しない

設計の良し悪しが最も表れるのは、 変更が入ったときです。

責任が分割され、 構造によって保証されている設計では、

  • 変更理由が一つに定まり
  • 修正箇所が自然に絞られ
  • 他の部分を疑わなくて済む

という状態になります。

これは、コードを修正した人が優秀だからではありません。

構造が、変更を制御している からです。


良い設計は、人間の思考コストを下げる

良い設計がされたコードは、 読んでいて楽です。

それは、 人が毎回判断しなくてよいからです。

  • これは考えなくてよい
  • ここは迷わなくてよい
  • これは構造が保証している

良い設計は、 人に頑張らせません。

構造に仕事をさせます。


良い設計は、属人化しない

属人化は、 人の問題だと思われがちです。

しかし本書では、

属人化は、 正しさが構造で保証されていない設計の結果 だと考えます。

特定の人だけが正しさを知っている状態は、 責任がコードではなく、 人に乗っている状態です。

良い設計では、

  • 判断は構造にあり
  • 人はそれに従うだけでよく
  • 後から来た人でも安全に触れる

という状態になります。


設計に正解はないが、説明は必要

設計に、 唯一の正解はありません。

ただし、

説明できない設計は、 責任の分割や保証の意図が曖昧な可能性があります。

なぜこの構造なのか。 なぜこの責任の分け方なのか。

それを言語化できる設計は、 構造として優れています。


この章のまとめ

設計とは、

責任の分割 + 構造による保証

です。

責任は、 人が意識して守るものではありません。

構造によって、保証されるべきもの です。

次の章では、 この「保証」が失われたとき、 コードの中で何が起きるのか。

「判断」という切り口から、 さらに掘り下げていきます。