2016-08-24 11 views
2

こんにちは 私はいくつかの条件チェックを含むメソッドを持ち、条件に従って文字列を追加するクラスを持っています。抽象的な工場パターンでこのコードをリファクタリングしようとしました。抽象ファクトリパターンデフォルトクラスの問題

私の問題は、デフォルトの表現クラスに関連しています。関連するフィルタに他のルールが適用されない場合は、デフォルトの式ルールを適用します。しかし、私のアプリケーションでは、 _expressionsリストのStandartExpressionインスタンスの順序に依存します。最初に追加された場合、他のルールはチェックされません。

私はそのパターンについて何か忘れてしまったと思います。私たちを手伝ってくれますか?

これは私のアプリケーションコードです:

public class Filter 
{ 
    private string _operator = "="; // =, !=, <,> ... 

    public string Name { get; set; } 
    public object Value { get; set; } 
    public string Operator { get { return _operator; } set { _operator = value; } } 

} 

Filter filter = null; 
StringBuilder whereClause = new StringBuilder(); 

for (int i = 0; i < array.Length; i++) 
{ 
    filter = array[i]; 

    if (filter.Value.ToString().ToLower().Equals("null")) 
    { 
     whereClause.Append(filter.Name + " " + filter.Operator + " null "); 
    } 
    else if (filter.Operator.ToLower().Equals("like")) 
    { 
     whereClause.Append(filter.Name + ".Contains(@" + i + ")"); 
    } 
    else 
    { 
     whereClause.Append(filter.Name + " " + filter.Operator + " @" + i); 
    } 
    whereClause.Append(" AND "); 
} 

さて、これはAbstract Factoryパターンコードです:

public interface ICustomExpression 
{ 
    bool ExpressionIsValid(Filter filter); 
    string GetExpressionStr(Filter filter, int index); 
} 


public class StandardExpression : ICustomExpression 
{ 
    public bool ExpressionIsValid(Filter filter) 
    { 
     return true; 
    } 

    public string GetExpressionStr(Filter filter, int index) 
    { 
     return filter.Name + " " + filter.Operator + " @" + index; 
    } 
} 

public class LikeExpression : ICustomExpression 
{ 
    public bool ExpressionIsValid(Filter filter) 
    { 
     return filter.Operator.ToLower().Equals("like"); 
    } 

    public string GetExpressionStr(Filter filter, int index) 
    { 
     return filter.Name + ".Contains(@" + index + ")"; 
    } 
} 
public class NullExpression : ICustomExpression 
{ 
    public bool ExpressionIsValid(Filter filter) 
    { 
     return filter.Value.ToString().ToLower().Equals("null"); 
    } 

    public string GetExpressionStr(Filter filter, int index) 
    { 
     return filter.Name + " " + filter.Operator + " null "; 
    } 
} 

public static class ExpressionFactory 
{ 
    private static List<ICustomExpression> _expressions = null; 
    public static List<ICustomExpression> Expressions 
    { 
     get 
     { 
      if (_expressions == null) 
      { 
       Build(); 
      } 
      return _expressions; 
     } 
    } 

    private static void Build() 
    { 
     _expressions = new List<ICustomExpression>(); 
     _expressions.Add(new NullExpression()); 
     _expressions.Add(new LikeExpression()); 
     _expressions.Add(new StandardExpression()); 
    } 
} 

が、それは私が私のアプリケーションコードにその構造を使用する方法です:

StringBuilder whereClause = new StringBuilder(); 
Filter filter = null; 
var array = filterList.ToArray(); 
for (int i = 0; i < array.Length; i++) 
{ 
    filter = array[i]; 

    foreach (ICustomExpression exp in ExpressionFactory.Expressions) 
    { 
     if (exp.ExpressionIsValid(filter)) 
      whereClause.Append(exp.GetExpressionStr(filter, i)); 
    } 


    whereClause.Append(" AND "); 
} 

答えて

2

あなたの気持ちは正しいです:明確にするために明示する必要がある "特別な"表現と "標準的な"表現の間には隠れた区別があります。

しかし私の目には、あなたの工場が実際にタイプ選択とインスタンシエーションを実際に処理しておらず、その責任の一部をクライアントに委譲しているという大きな問題があります。すべてのクライアントは、コレクションプロパティExpressionsをどのように扱うか知っていなければならず、したがって前述の暗黙的な区別についても知っていなければなりません。

ExpressionFactoryのクライアントは、正しいICustomExpressionインスタンスを取得するためにフィルタを渡すのが理想的です。 (あなたのケースでは、というか選択)

public static class ExpressionFactory 
{ 
    private static StandardExpression _standardExpression = new StandardExpression(); 

    private static ICustomExpression[] _specialExpressions = new [] 
    { 
     (ICustomExpression)new NullExpression(), 
     (ICustomExpression)new LikeExpression() 
    }; 

    public static ICustomExpression GetBy(Filter filter) 
    { 
     var match = _specialExpressions.SingleOrDefault(e => e.ExpressionIsValid(filter)); 

     if (match == null) 
      return _standardExpression; 

     return match; 
    } 
} 

式が作成されますどのようにルールを今だけの工場で知られているので、1つの場所で実装されています。ここでは、このように見えるかもしれない方法です。

「特別」と「標準」の式を明示的に区別しているため、実装はもはやICustomExpressionが追加される順序に依存しません。工場の使用が今よりストレートフォワードになるという

注:https://dotnetfiddle.net/uzVJhM

ところで:ここ

for (int i = 0; i < array.Length; i++) 
{ 
    filter = array[i]; 
    var exp = ExpressionFactory.GetBy(filter);   
    whereClause.Append(exp.GetExpressionStr(filter, i));   
    whereClause.Append(" AND "); 
} 

は、リファクタリング、コードの実施例である、あなたの実装では、より多くのように見えますfactory method patternのインスタンスです。

+0

これは私が探しているものです。パターンについて私が迷っているものを手に入れました。ありがとう!!! – ahmet

関連する問題