化学薬品をコンテナに保管する倉庫を考える。化学薬品には揮発性だとか非活性だとか色々ある。化学薬品によって適切なコンテナ、どのような組み合わせで保管できるかなど規則がある。
化学薬品をコンテナに安全かつ効率的に配置するソフトウェアを構築することが目標。
最初に化学薬品を取り出しコンテナに配置する処理を書いてみたが妥当性検証の問題に直面した。
規則を明確にしてみる。実装の検証にも役立つはずだ。
各化学薬品には次のコンテナ仕様がある。
化学薬品 | コンテナ仕様 |
TNT | 強化コンテナ |
砂 | |
生体サンプル | 爆発物と一緒にしてはいけない |
アンモニア | 通気コンテナ |
Container Specificationsとして記述してみよう。規約を満たすかを検証できるはずである。
コンテナ機能 | 内容物 | 仕様を満たしているか |
強化型 | TNT 20ポンド、砂 500ポンド | OK |
生体サンプル 50ポンド | OK | |
アンモニア | NG |
Container SpecificationのisSatisfied()メソッドは必要なContainerFeatures?かどうかを確認する実装となる。例えば、爆発物では「強化」機能を探す。
(コード例は本書のとおり)
爆発物を組み立てるクライアントのサンプル。
ContainerオブジェクトのisSafelyPacked?()メソッドは、Container自身が保持するChemicalsによって指定される全ての機能を満たしているかを確認する。
(コード例)
ここで、一覧を取り出し、危険な状況を報告する監視アプリケーションを書くことができる。
(コード例)
しかし、これは求められたソフトウェアではない。業務担当者にそうした機会を知らせるのには良いが、我々は梱包の設計を担当してきたのだ。我々がすべきことは梱包の検査である。こうしたドメイン解釈とSPECIFICATIONに基づいたモデルのおかげで、DrumsとContainersのコレクションを規則どおりに梱包するSERVICEに対して、明確でシンプルなインターフェイスを定義できる。
(コード例) /*注意:pack()の最後で、Containerは自身を保持するDrumのContainerSpecification?を満足しなければならない。だめなら例外がスローされる。*/
Packerサービスの責務を完全に満たす規約を設計することはアプリケーションの停止を回避し、モデルを表す設計を乱さない(10章のDeclarative Style of Design、15章のCOHESIVE MECHANIXMを見てね)。しかしなお、梱包を規定するルールはドメインオブジェクトから十分に抽出できていない。