No more Death March

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

インターフェースを考える(4)IAction

C#実践開発手法よりIActionインターフェースです。

namespace Nmdm.Actions
{
    public interface IAction<TContext>
    {
        void Do(TContext context);
    }
}

単一の引数を受け取る戻り値の無いインターフェースで、
引数は型パラメータで指定出来る・・・と

使いどころはどこなんだろう。
こないだ書いたITaskに引数が一つ付いただけなわけですが・・・
nomoredeathmarch.hatenablog.com

手段と目的がごっちゃになってるけど何かスマートな使い方は出来ないものか・・・

たとえば、ドメインイベントのハンドラにイベントの具体的な処理を着脱できるようにするとか?
まずIHandlerインターフェス(前の記事ではISubscriberだったけどC#実践開発手法の表記に合わせた。)

namespace Nmdm.Events
{
    public interface IHandler
    {
        void Handle(IEvent value);
        bool CanHandle(IEvent value);
    }
}

こいつの実装クラスとして、着脱可能なアクションをコンストラクタで受け取るHandlerクラス

using System;
using Nmdm.Actions;

namespace Nmdm.Events
{
    public sealed class Handler<T> : IHandler 
        where T:IEvent
    {
        public Handler(IAction<T> action)
        {
            if (action == null) throw new ArgumentNullException("action");
            this.Action = action;
        }

        private IAction<T> Action { get; }

        public bool CanHandle(IEvent value)
        {
            if (value == null) return false;
            return value is T;
        }

        public void Handle(IEvent value)
        {
            if (!this.CanHandle(value)) return;
            this.Action.Do((T)value);
        }
    }
}

コンストラクタでIAction(制約でTはIEventとする。)を受け取ってprivate変数へ。
あとはHandlerクラスがドメインイベントの通知を受け取る度にIActionが実行されると。

ドメインイベントとは違うけど、MVVMのメッセージ通知とかに使えるかな?
イベントでメッセージの内容を受け取って、アクション側でメッセージ表示の具体的な方法を実装する。
最初は標準のメッセージボックスを表示してたけど、そのうちカスタマイズしたメッセージボックスにすげ変えると・・・

パブリッシャに予約してなければ単体テストもそのままで良さそう。
イベント通知される場面なら↓みたいなIActionのモックと入れ替えても良いのか。

namespace Nmdm.Actions
{
    public sealed class ActionMock<T> : IAction<T>
    {
        public void Do(T context)
        {
        }
    }
}

「イベントの通知を受け取る」っていう仕事と「イベントの情報を読み込んで処理を実行する。」っていう仕事を分離して実装出来ますね。