我创建一个动态查询生成器发送到另一个组件(报表生成器)。
查询的某些部分有占位符。例如:
SELECT DISTINCT ID, NAME AS VALUE FROM EVENTS
WHERE {{ESTABLISHMENTFILTER.ID}} IS NULL OR ESTABLISHMENT_ID = {{ESTABLISHMENTFILTER.ID}}
的数据,以在where子句可以是整数,字符串,日期,被取代,每一个都有一个不同的行为(例如:包括在字符串周围的值单引号案件)。
我的第一个方法是创建一个枚举:
public enum FilterType
{
Integer,
String
}
,并使用它像这样(在例如业务层)
switch (filter.Type)
{
case FilterType.Integer:
//Do replace logic for an integer
break;
case FilterType.String:
//Do replace logic for a string
break;
default:
break;
}
我也申请SOLID原则,以我的代码,我发现这可能会破坏OCP。所以我重构使用一个基类
public abstract class FilterType
{
public abstract string Replace(string baseString, string oldValue, string newValue);
}
每种类型都有其自己的实现:
public class FilterTypeInteger : FilterType
{
public override string Replace(string baseString,string oldValue, string newValue)
{
//Do logic to replace for an Integer type
}
}
问题
固溶工作了我的测试,但在生产代码数据库中有一个int列来确定类型。所以我基本上把'switch-case'逻辑转移到数据层,它将不得不检查这个列来实例化正确的FilterType(下面的代码是一个伪代码,因为我还没有实现它):
if (dataReader["FILTERTYPE"] == 1)
filter.Type = new FilterTypeInteger();
else if (dataReader["FILTERTYPE"] == 2)
filter.Type = new FilterTypeString();
的课题
1)实施上述的 '的if-else' 逻辑被打破了OCP的方法?因为如果创建一个新的类型,则必须实现一个新的else子句
2)是否有另一种方法将SOLID OCP原则保留在数据库和业务代码中,而不使用开关或if-else子句?
如果您正在构建SQL语句,为什么不使用库和准备好的语句来为您处理这些事情? – Seth
查询是通过现有的用户界面创建的,因此它必须支持在模板中定义的占位符。它也必须支持级联查询这就是为什么我决定构建自己的组件。 –