インターフェースを考える(10)ISpecificationのテスト
この記事では以下の記事で実装したクラスをテストしてみて、クライアントコードの具合を考えてみます。
記事の順序やらテストのタイミングがぐちゃぐちゃですが、チラシの裏ブログなのでご容赦を・・・
nomoredeathmarch.hatenablog.com
まず、最初のテストコードは以下の通り
using Nmdm.Specifications; using Microsoft.VisualStudio.TestTools.UnitTesting; namespace Nmdm.SpecificationsTests { [TestClass] public class SpecificationsTest { [TestMethod] public void TestMethod() { var satisfiedSpec = new SpecificationIsSatisfied<object>(); Assert.IsTrue(satisfiedSpec.IsSatisfiedBy(new object())); var notSatisfiedSpec = new SpecificationIsNotSatisfied<object>(); Assert.IsFalse(notSatisfiedSpec.IsSatisfiedBy(new object())); } } }
固定でtrueやfalseを返すSpecificationクラスの動作を確認。
型パラメータはなんでも良いのでobjectクラスを指定する。
で、続いてAndSpecificationの動作確認、まずは拡張メソッドを使わないで書くと↓のような具合
// AndSpecificationをNewして書くと。 ISpecification<object> spec1 = new AndSpecification<object>(satisfiedSpec, satisfiedSpec); Assert.IsTrue(spec1.IsSatisfiedBy(new object())); ISpecification<object> spec2 = new AndSpecification<object>(satisfiedSpec, notSatisfiedSpec); Assert.IsTrue(spec1.IsSatisfiedBy(new object()));
これだとAndやOrが続いた時にnew AndSpecification(new AndSpecification(…))とネストしてってわかりにくい。
拡張メソッドを使って書くと。
// AndSpecificationを拡張メソッドで書く Assert.IsTrue(satisfiedSpec.And(satisfiedSpec).IsSatisfiedBy(new object())); Assert.IsFalse(satisfiedSpec.And(notSatisfiedSpec).IsSatisfiedBy(new object()));
という具合に数珠つなぎに書けると…
うーん、
これってITaskやIAction等、汎用的なインターフェースと拡張メソッドを駆使すれば、
個々のドメインモデルの実装を省コード化出来るような気がする・・・
ドメインモデルはデータ構造を提供し、個々の処理やチェック処理は小さいIActionやISpecificationを組み合わせて実現すると・・・
ただそれをやってしまうと、ドメインモデルがただの入れ物クラスになってしまうんだよなぁ・・・
良し悪しはともかく、引き続きインターフェースをこねくりまわすと良い考えが浮かぶかもしれない・・・