把算法做成可插拔的插件

针对同一个问题,如果需要不同的算法来解决,那么我们最好把不同的算法类提出一个抽象基类,让不同的算法来重写它提供的接口,在应用层通过基类指针来调用不同的算法

比如说不同国家有不同的税率计算方案,那么我们就可以让税率计算器持有一个抽象基类的计算方案,然后把对应国家的具体计算算法传给它

再举个例子,那么多排序算法,可以提升出一个抽象基类strategy,具体要使用哪个排序,传给实际执行排序的应用

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
93
94
95
96
97
98
99
100
101
102
103
#include <iostream>
#include <memory>
#include <vector>

class strategy {
public:
virtual void Sort(std::vector<int> &vec) = 0;
virtual std::string Info() = 0;
virtual ~strategy() {}
};

class Sorter {
public:
void SetStrategy(std::unique_ptr<strategy> st) {
m_strategy = std::move(st);
}

void Process(std::vector<int> vec) {
for(auto e : vec) {
std::cout << e << " ";
}
std::cout << std::endl;

std::cout << "正在使用" << m_strategy->Info() << "排序" << std::endl;
m_strategy->Sort(vec);

for(auto e : vec) {
std::cout << e << " ";
}
std::cout << std::endl;
}
private:
std::unique_ptr<strategy> m_strategy;
};

class BubbleSort : public strategy {
public:
void Sort(std::vector<int> &vec) override{
for(int i = 0; i < vec.size(); i++) {
for(int j = 0; j < vec.size() - 1; j++) {
if(vec[j] > vec[j+1]) {
int tmp = vec[j];
vec[j] = vec[j+1];
vec[j+1] = tmp;
}
}
}
}
std::string Info() override {
return "冒泡排序";
}
};

class QuickSort : public strategy {
public:
void Sort(std::vector<int> &vec) override{
InnerSort(vec, 0, vec.size() - 1);
}

std::string Info() override {
return "快速排序";
}
private:
void InnerSort(std::vector<int> &vec, int left, int right) {
if(left >= right) {
return;
}

int i = left;
int j = right;
int flag = vec[i];

while (i < j)
{
while (i < j && vec[j] >= flag)
{
j--;
}
vec[i] = vec[j];

while (i < j && vec[i] <= flag)
{
i++;
}
vec[j] = vec[i];
}
vec[i] = flag;

InnerSort(vec, left, i - 1);
InnerSort(vec, i + 1, right);
}
};

int main() {
Sorter x;

x.SetStrategy(std::make_unique<BubbleSort>());
x.Process({7,8,2,5,6,4,10});

x.SetStrategy(std::make_unique<QuickSort>());
x.Process({7,8,2,5,6,4,10});
return 0;
}