mercredi 24 août 2016

Abstract Factory Pattern Default Class Issue

Hi, I've a class which has a method with some condition checks and append a string according to condition. I tried to refactor this code with abstract factory pattern.

My problem is related to default expression class. If none of other rules applies to related filter, then I want to apply default expression rule. However on my application; it depends the order of StandartExpression instance order in the _expressions list. If it is added first then the other rules will not be checked.

I think I missed something about that pattern. Could you help me?

This is my application code:

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

Now, this is the abstract factory pattern code:

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

And that is how I used that structure on my application code:

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

Aucun commentaire:

Enregistrer un commentaire