簡體   English   中英

抽象工廠模式默認類問題

[英]Abstract Factory Pattern Default Class Issue

嗨,我有一個類,該類的方法帶有一些條件檢查並根據條件附加字符串。 我試圖用抽象工廠模式重構此代碼。

我的問題與默認表達式類有關。 如果沒有其他規則適用於相關過濾器,那么我想應用默認表達式規則。 但是在我的申請中; 它取決於_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 ");
}

現在,這是抽象的工廠模式代碼:

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 ");
}

您的感覺是正確的:“特殊”和“標准”表達式之間存在隱藏的區別,為清楚起見,應明確表達它們。

但是,在我看來,更大的問題是您的工廠實際上不是在自行處理類型選擇和實例化,而是將部分責任委托給客戶。 每個客戶端都必須知道如何使用集合屬性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;
    }
}

現在,僅由工廠知道如何創建(或在您的情況下選擇)表達式的規則,因此可以在一個地方實現。

我還明確指出了“特殊”和“標准”表達式之間的隱式區別,因此實現不再依賴於ICustomExpression的添加順序。

請注意,工廠的用法現在變得更加簡單:

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 ");
}

這是重構代碼的工作示例: https : //dotnetfiddle.net/uzVJhM

順便說一句:您的實現看起來更像是工廠方法模式的實例。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM