インターフェースを考える(9)インターフェースの組み合わせ
前回ISpecificationでAndやOrといった論理演算を拡張メソッドで簡単に記述出来るようにしましたが、
思うにこれって他の汎用的なインターフェースにすべて適用出来ますね。
以下前回の記事
nomoredeathmarch.hatenablog.com
ただ適用する際の注意点としては
・拡張メソッド内で具体的な処理(AndやOrといった汎用性の高いものは別として)に依存させない。
・拡張メソッドのシグネチャのいずれかに、自身が提供する型が含まれる。
今回はこれを引数、戻り値の無い、ITaskに適用してみます。
まずITaskの復習
namespace Nmdm.Tasks { public interface ITask { void Do(); } }
うん、シンプル、なにかを受け取らず、なにも返さず、ただDoメソッドの呼び出しをトリガーになんらかの処理を実行する。
このITaskを連続で実行するためのクラスとして用意したのがCompositeTask、
前回のAndSpecificationと同様に手直ししたものが以下の通り。
namespace Nmdm.Tasks { public sealed class CompositeTask:ITask { public CompositeTask(ITask one,ITask other) { this.One = one ?? new NullTask(); this.Other = other ?? new NullTask(); } private ITask One { get; } private ITask Other { get; } public void Do() { this.One.Do(); this.Other.Do(); } } }
これを毎回New CompositeTaskを呼ばなくて良いように拡張メソッドを実装する。
namespace Nmdm.Tasks { public static class CompositeTaskExtension { public static ITask Add(this ITask one,ITask other) { return new CompositeTask(one, other); } } }
これでクライアント側はITaskを実装したすべてのクラスについて(ITask).Add(ITask).Do()という具合に記述出来るようになると。