抽象工厂模式默认 Class 问题
Abstract Factory Pattern Default Class Issue
你好,
我有一个 class ,它有一个带有一些条件检查的方法,并根据条件附加一个字符串。我试图用抽象工厂模式重构这段代码。
我的问题与默认表达式 class 有关。如果其他规则的 none 适用于相关过滤器,那么我想应用默认表达式规则。但是在我的申请中;它取决于 _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 ");
}
您的感觉是对的:"special" 和 "standard" 表达式之间存在隐藏的区别,为了清楚起见,应该将其明确化。
但是,在我看来,更大的问题是您的工厂实际上并没有自行处理类型选择和实例化,而是将部分责任委托给了客户。每个客户都必须知道如何使用集合 属性 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;
}
}
如何创建表达式(或者更确切地说,在您的情况下选择表达式)的规则现在只有工厂知道,因此在一个地方实现。
我还明确了 "special" 和 "standard" 表达式之间的隐含区别,因此实现不再依赖于添加 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
顺便说一句:您的实现看起来更像是 factory method pattern.
的一个实例
你好, 我有一个 class ,它有一个带有一些条件检查的方法,并根据条件附加一个字符串。我试图用抽象工厂模式重构这段代码。
我的问题与默认表达式 class 有关。如果其他规则的 none 适用于相关过滤器,那么我想应用默认表达式规则。但是在我的申请中;它取决于 _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 ");
}
您的感觉是对的:"special" 和 "standard" 表达式之间存在隐藏的区别,为了清楚起见,应该将其明确化。
但是,在我看来,更大的问题是您的工厂实际上并没有自行处理类型选择和实例化,而是将部分责任委托给了客户。每个客户都必须知道如何使用集合 属性 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;
}
}
如何创建表达式(或者更确切地说,在您的情况下选择表达式)的规则现在只有工厂知道,因此在一个地方实现。
我还明确了 "special" 和 "standard" 表达式之间的隐含区别,因此实现不再依赖于添加 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
顺便说一句:您的实现看起来更像是 factory method pattern.
的一个实例