No more Death March

あるSEのチラシの裏 C# WPF

インターフェースを考える(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を組み合わせて実現すると・・・
ただそれをやってしまうと、ドメインモデルがただの入れ物クラスになってしまうんだよなぁ・・・

良し悪しはともかく、引き続きインターフェースをこねくりまわすと良い考えが浮かぶかもしれない・・・