【问题标题】:Abstract Factory Pattern Default Class Issue抽象工厂模式默认类问题
【发布时间】:2016-08-24 13:28:56
【问题描述】:

你好, 我有一个类,它有一个带有一些条件检查的方法,并根据条件附加一个字符串。我试图用抽象工厂模式重构这段代码。

我的问题与默认表达式类有关。如果没有其他规则适用于相关过滤器,那么我想应用默认表达式规则。但是在我的申请中;它取决于 _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 ");
}

【问题讨论】:

    标签: c# design-patterns abstract-factory


    【解决方案1】:

    您的感觉是对的:“特殊”和“标准”表达之间存在隐藏的区别,应该明确说明。

    但是,在我看来,更大的问题是您的工厂实际上并没有自己处理类型选择和实例化,而是将部分责任委托给其客户。每个客户都必须知道如何使用集合属性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;
        }
    }
    

    现在只有工厂知道如何创建(或者更确切地说是选择,在您的情况下)表达式的规则,因此在一个地方实现。

    我还明确区分了“特殊”和“标准”表达式,因此实现不再依赖于添加 ICustomExpressions 的顺序。

    请注意,工厂的使用现在变得更加直接:

    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

    顺便说一句:您的实现看起来更像factory method pattern 的一个实例。

    【讨论】:

    • 绝对是我要找的。我得到了我所缺少的关于模式的东西。谢谢!!!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-09-06
    • 1970-01-01
    相关资源
    最近更新 更多