複数の設定値によって、別の複数の設定値が決まるようなアレ
今日悩みながら書いたコードについてメモ。C#です。
まず、何かDTOがあると思ってください。
public class SomeObject { public string Fuga { get; set; } public int Piyo { get; set; } public bool IsFoo { get; set; } public bool IsBar { get; set; } }
このDTOのIsFooとIsBarが正しく設定されたオブジェクトが、出力です。
設定に必要な情報が、入力です。
次に、入力と出力のマッピングを定義します。入力はint配列、出力は設定の処理そのものとします。
public class Mapping : IEqualityComparer<int[]> { public IDictionary<int[], Func<SomeObject, SomeObject>> getPatterns() { IDictionary<int[], Func<SomeObject, SomeObject>> dic = new Dictionary<int[], Func<SomeObject, SomeObject>>(this){ {new[] {0, 0}, setStatus(false, true)} , {new[] {0, 1}, setStatus(true, true)} , {new[] {1, 0}, setStatus(false, false)} , {new[] {1, 1}, setStatus(true, false)} }; return dic; } private Func<SomeObject, SomeObject> setStatus(bool foo, bool bar) { Func<SomeObject, SomeObject> func = delegete(SomeObject obj){ obj.IsFoo = foo; obj.IsBar = bar; return obj; }; return func; } bool IEqualityComparer<int[]> Equals(int[] x, int[] y){ if (x.Length != y.Length ) { return false; } for( int n = 0; n < x.Length; n++ ) { if ( x[n] != y[n] ){ return false; } } return true; } int IEqualityComparer<int[]> GetHashCode(int[] x) { int sum = 0; foreach (int n in x) { sum += n.GetHashCode(); } return sum; } }
上のコードでは省略しましたが、扱う入力状態は数百パターンあるものとします。
(実際には、状態表のような設計書を先に別途作り、それを見ながら実装するような感じです。お察しください)
使う側のコードはこうなります。
public class UserCode { public SomeObject exec(){ var obj = new SomeObject(); var mapping = new Mapping(); var patterns = mapping.getPatterns(); // 入力を与える var pattern = patterns[ new[] { getHoge() // 何らかの仕様にしたがって0か1が返ってくると思ってほしい , getMoga() // ここも同じ } ]; pattern.Invoke(obj); return obj; } }
Keyを配列にせずクラスにすべきとか、いろいろありますが、根本的に改善するにはどうすればよいか。