守り方は、二通りしかない
「このメソッドは、nullを返さない」。
コードのどこにも書いていないのに、呼び出し側が当てにしている決まりが、どのコードにもあります。この記事では、これを仕様(または約束事) と呼びます。
仕様の守り方は、二通りしかありません。構造で守るか、規約で守るか。
構造で守る
構造で守るとは、仕様をコードの形に落としてしまうことです。
「nullを返さない」なら、戻り値の型をstring?ではなくstringにする。(補足、C#のnull安全の文脈)
もし仕様の約束事を破ればビルドが失敗するか、少なくとも警告が出ます。
規約で守る
規約で守るとは、仕様を
- コメント、ドキュメント、命名
- レビューとテスト
で見張ることです。
スライドの言葉でいえば『形で守るか、張り紙で守るか。』
つまり「人間の注意力を燃やして」守ることです。
基準(物差し)にして仕分け
「構造で守るか、規約で守るか」を物差しにして、五原則を仕分けてみます。
-
開放閉鎖の原則(OCP)はこの軸に乗りません
OCPは「守り方を選ぶ規則」ではなく、「変更せずに拡張できたか」という到達目標です。 -
単一責任の原則(SRP)も抽象度が違います
スライドの言葉で言えば、運転手ごとに、車を分ける話。もし相席すると、別々の依頼が同じファイルに届くので、そこから違反を検知できます。
残る三つ。
当初、私は、三つは同じレベル感だと考えていました。
しかし「構造で守るか、規約で守るか」で見ると、少し違って見えます。
| 原則 | 形の整え方 | 違反すると |
|---|---|---|
| インターフェース分離の原則(ISP) | 差込口を、細く割る | 宣言にないメソッドは、呼びたくても呼べない |
| 依存関係逆転の原則(DIP) | 依存の向きを、参照で縛る | 参照のない方向へは、ビルドが通らない |
これらは構造で守れます。(構造図やコンパイラで違反を検知できるの意味です)
(メソッド名の綴りを変えればビルドで止まる、これはコンパイラで違反を検証できる例です。コンパイラは「構造で守る」の中でも一番安価な検証器です)
しかし、リスコフの置換原則(LSP)だけが、構造で守れません。
LSP定番の例で言えば、正方形は、長方形の形のまま「幅を変えても、高さは変わらない」という約束事を破ります。
言いたいのは、
どれだけインターフェースの形を工夫しても、振る舞いの仕様は形では守れません。守るには、言葉に書いたり、レビューを重ねるなど、人間の注意力を燃やして、見張るしかありません。
まとめると、『I・Dは、構造で守れる。Lは、規約でしか守れない。』
よくある売り文句が招く困りごと
『置き換え可能』はインターフェースの売り文句です。
- 実装を差し替えられます
- モックに差し替えてテストできます
- 将来の実装に差し替えられます
しかしこれらは、すべて(先ほど見たように)構造では守れません。
フィールド名という「形」はコンパイラの管轄内。その先の置き換えられた実クラスの振る舞いは管轄外です。
検証する手段としてはテストをしっかり書くことです。しっかり書いているか注意して見守る必要があります。
保証書を発行しないという判断
ここから、設計判断の話になります。
いわば、インターフェースを一枚切ることは、保証書を一枚発行することです。
『ここに挿さる実装は、どれを挿しても、同じように動きます。』という約束事です。
しかし、機械がチェックできるのは、シグネチャ(メソッドの名前と型の並び)だけ。
「同じように動く」の部分を守るのは、規約とテスト、つまり、人間の注意力が燃料です。
そのため
- まだ差し替えの予定がないインターフェース
- いつか役に立つかもしれない再利用性
- 念のための置き換え可能性
こういった早すぎる実装は、保証書を乱発しているのと同じです。
であれば、インターフェース化を遅らせることは、遅らせた分だけ、より少ない注意力で回すこととなり、良い設計判断となりえます。
これは、確信のない機能は入れない、という設計方針(ミニマリティ)です。
もし、入れてしまえば、皆が必要性を考えずに使う。仮に、外しておいても、本当に必要なときには苦情が来る。
苦情駆動ですね。
後回しにできるもの、できないモノ
残念ながら、後回しにできるのは、保証書を発行するタイミングだけです。仕様を守ること自体は、後回しにできません。
守るべき仕様そのものは、消えないからです。もしも差し替えが必要になったら、規約(人間の注意力)で守るようにします。
発行するなら、三つの条件で
では、保証書を発行すると決めたら、どうやって守るのか?
そのヒントについての話しです。
規約で守る(人間の注意力が燃料)を補助する道具として、三つの条件があります。
- 呼び出しの入口を縛る「事前条件」
- 出口を縛る「事後条件」
- いつ見ても成り立つ「不変条件」
スライド版で「形に書けない約束」と呼んだ三点セットです。
書き方と、破られ方の本体は、ここでは長くなりますので、契約による設計(Design by Contract / DbC)にゆずります。
さらに、もう一つ加えたいのが「一度確定した値は、以後変わらない」という条件。履歴制約です。
なぜか日本語版では説明が省かれているので英語版で、
Immutable Point/Mutable Point の議論です。これも発見が面倒な約束事の破り方です。
問い
そのインターフェース早すぎませんか
この記事について
先日、SOLID原則の設計原則を伝えるためのスライドを作成しました
この記事はその「やさしく解説 設計編・中級」を深掘りするものです。
中級#3「形は合っていたのに」
スライドについて
SOLID原則をやさしく伝えるためのスライドです。
例えるなら、このスライドは「守破離」でいえば、「守」になります。
この「守」では、まず審美眼を養うことを優先します。
そのため、語れなかったもの、省いたものが数多くあります。
今回は、「守」で説明した手段を「適用しない」場面について語ります。
つまり「破」の記事です。
守:スライド版「やさしく解説 設計編・中級」
私の記事よりもわかりやすい記事:「シン・リスコフの置換原則 〜現代風に考えるSOLIDの原則〜」(Uzabase for Engineers, 2026-04)