DbCによる非機能要件の定義
契約による設計(DbC)は、非機能的な要件、特に
パフォーマンスやリソース制限に関する契約を定義するために極めて有効です。
機能的な振る舞い(「入力が正の数なら、出力はその平方根である」など)だけでなく、
「システムが安定して稼働するための前提条件やルール」 を契約として明文化できます。
なぜ非機能要件も契約設計できるのか?
契約による設計の核心は、コンポーネント間の責任の所在を明確にすることにあります。
そして、これは、機能・非機能を問いません。
例えば、以下の表のように、非機能も表現できます。
コンサート会場のアナロジー
この関係は、コンサート会場のルールに似ています。
事前条件 (観客の責任)
会場に入る前に、観客は 「有効なチケットを持っている」 必要があります。
チケットを持たずにゲートに来た場合、悪いのは観客であり、警備員は入場を拒否します。
不変条件 (会場側のルール)
会場側は、常に 「消防法で定められた定員を超えない」 というルールを守らなければなりません。
これは会場の安全(安定性)を保つための絶対的なルールです。
たとえ有効なチケットを持つ観客が来ても、定員に達していれば、会場はそれ以上の入場を拒否する責任があります。
事後条件 (アーティストの責任)
コンサートが終わった後には、「アーティストが最低90分は演奏した」 という事実が保証されなければなりません。
実装とメリット
これらの非機能的な契約は、コード内のassert
文だけで実装されるとは限りません。
多くの場合、より広範なアーキテクチャコンポーネントによって実現されます。
事前条件のチェック場所
API Gateway、ロードバランサ、クライアント側のライブラリ
不変条件のチェック場所
サーバー側のアプリケーションロジック、サイドカー (例:サービスメッシュ)、サーキットブレーカー
メリット
このアプローチの最大のメリットは、
非機能要件を「努力目標」や「ドキュメント上の空虚な記述」から、
「検証可能で、違反した際の責任の所在が明確な、生きたルール」
へと昇華させる点にあります。
これにより、システムの安定性と信頼性が設計レベルで大幅に向上します。
The Layered Contract:A Chain of Trust
クリーンアーキテクチャの同心円は、まさに 責任の連鎖(Chain of Responsibility) であり、各層が次のより内側の層に対してセキュリティに関する契約(Contract)を果たしていく「信頼の連鎖」と見なすことができます。
🏰 アナロジー:城のセキュリティチェックポイント
このプロセスは、厳重に警備された城に入っていくプロセスそのものです。
1. 城門 (Presenters / Controllers)
役割:最も外側の防御線
ここでは、身元確認(認証)、通行証の確認(ロールベースの認可)、そして 危険物の持ち込みチェック(入力バリデーション/サニタイズ) を行います。
契約 (事前条件)
この城門の警備員(Presenter)は、ここを通過する者(リクエスト)が
「何者であり、最低限の立ち入り資格を持ち、明らかな脅威ではないこと」
を保証する責任を負います。
2. 本丸の入口 (Use Cases / Interactors)
役割:より内側の防御線
ここでは、具体的な目的に基づいた権限をチェックします。
「この人物は、本当に『宝物庫』に入る権限を持っているのか?」
といった、ビジネスロジックに基づいた詳細な認可です。
契約 (事前条件)
この入口の衛兵(Use Case)は、城門の警備員が仕事を果たしたことを前提としています。
つまり、
「身元不明者や武器を持った人物は、そもそもここまで到達しない」
と信頼しています。
その上で、自身の責任である、「宝物庫へのアクセス権」のチェック に集中します。
契約による設計(DbC)としての責務
この関係を契約の言葉で表現すると、以下のようになります。
このアプローチのメリット
この設計は、クリーンアーキテクチャとセキュリティ原則がもたらすメリットを最大化しています。
関心の分離
Use Caseは、JWTの解析方法やSQLインジェクション対策といった「外側の世界」の詳細を知る必要がなくなります。
ビジネスロジックの検証 という、本来の責務に集中できます。
テストの容易性
Use Case層のセキュリティ(「このユーザーはこの注文をキャンセルできるか?」)をテストする際に、HTTPリクエストや認証トークンをモックするだけで済み、テストが非常にシンプルになります。
堅牢な多層防御
攻撃者は、まず外側の一般的なセキュリティチェックを突破し、さらに内側の文脈に応じたビジネスレベルのセキュリティチェックをも突破しなければならず、防御が非常に厚くなります。
注意すべき点
ただし、この契約による設計の事前条件をクリアしたものを信頼しきるのは危険です。
特にクリーンアーキテクチャの同心円における、外側の層からより内側に来る部分は、
「事前条件を通過したものの、そのリクエストは攻撃者かもしれない。」
と警戒すべきチェックポイントです。
そのため、この契約による設計だけでなく、防御プログラミング的発想で、内側でもチェックをすべきです。
もちろん、すべての場所に
・契約による設計
・防御プログラミング
両方を実装するのは、コストがかかり過ぎるので、重要なビジネスロジック部分とかに限定して適用しましょう。