在某个项目当中,使用的使Dapper+WebApi进行构建的,在进行一些列表查询的时候需要根据不同的State来构建不同的SQL语句。之前是直接使用的switch
来一个个匹配,需求增加的话,又得再加一个case。长久以往,整个查询接口臃肿不堪,离职前夕终于看不下去了,重构了一番,兹此记录。
原结构
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleTest
{
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
class Program
{
static void Main(string[] args)
{
}
public List<Product> GetByStateToList(int ConditionState)
{
StringBuilder _queryString = new StringBuilder();
switch (ConditionState)
{
case 1:
_queryString.Append("查询1");
break;
case 2:
_queryString.Append("查询2");
break;
case 3:
_queryString.Append("查询3");
break;
default:
_queryString.Append("查询4");
break;
}
var _queryResult = QueryDatabase(_queryString.ToString());
return _queryResult;
}
public List<Product> QueryDatabase(string queryStr)
{
// .....查询处理
return new List<Product>();
}
}
}
|
弊端十分明显,这里我是简化了查询语句,实际情况使每个case至少有十几行代码用于构建查询语句,随着业务变更不断加快,那么我们的GetByStateToList
也会变得越来越臃肿,难以维护。
那么如何重构呢?
第一步,拆!!!
臃肿的原因就是因为在这个函数内部塞了太多的语句和分支条件,那么我们首先要把每个查询语句构建分离成一个类,将查询语句的构建放在这个独立的类内部进行操作。
第二步,统一接口
所有构建SQL语句的类都会有一个Build方法,这个方法用于构建具体的SQL语句,那么我们可以通过一个统一的接口来调用这个Build进行操作。
第三步,自动匹配
要实现自动匹配,每个类需要在其内部维护一个State常量,这个常量用于判断什么State实例化什么构造类。
下面我们就来实战演练了
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Reflection;
namespace ConsoleTest
{
public class Product
{
public string Name { get; set; }
public double Price { get; set; }
}
public abstract class SQLBuilder
{
private static List<SQLBuilder> _builders = null;
public int State { get; protected set; }
public static ISQLBuilder GetSQLBuilder(int state)
{
if (_builders == null)
{
_builders = new List<SQLBuilder>();
var _types = Assembly.GetExecutingAssembly().GetTypes();
foreach (var _type in _types)
{
if (_type.GetInterface(typeof(ISQLBuilder).FullName) != null)
{
_builders.Add(Activator.CreateInstance(_type) as SQLBuilder);
}
}
}
var _builder = _builders.Where(x => x.State == state).FirstOrDefault();
return _builder as ISQLBuilder;
}
}
public interface ISQLBuilder
{
string Build();
}
public class SQLBuilderNo1 : SQLBuilder, ISQLBuilder
{
public SQLBuilderNo1() => State = 1;
public string Build() => "查询1";
}
public class SQLBuilderNo2 : SQLBuilder, ISQLBuilder
{
public SQLBuilderNo2() => State = 2;
public string Build() => "查询2";
}
public class SQLBuilderNo3 : SQLBuilder, ISQLBuilder
{
public SQLBuilderNo3() => State = 3;
public string Build() => "查询3";
}
class Program
{
static void Main(string[] args)
{
ISQLBuilder _builder = SQLBuilder.GetSQLBuilder(2);
Console.WriteLine(_builder.Build());
_builder = SQLBuilder.GetSQLBuilder(3);
Console.WriteLine(_builder.Build());
Console.ReadKey();
}
public List<Product> GetByStateToList(int ConditionState)
{
string _queryStr = string.Empty;
var _queryResult = QueryDatabase(_queryStr);
return _queryResult;
}
public List<Product> QueryDatabase(string queryStr)
{
// .....查询处理
return new List<Product>();
}
}
}
|
结果: