在许多现代语言中, 我们时常能够看到链式编程.

比如在 CSharp 中, 我们可以对一个对象进行链式编程, 例如:

1
2
3
4
5
6
7
var str = "Hello, World!";
var result = str
.Replace("Hello", "Hi")
.Replace("World", "Dynesshely")
.ToUpper();
Console.WriteLine(result);
// Output: HI, DYNESSHELY!

这是因为 ReplaceToUpper 方法返回的仍是 String 对象, 所以我们可以继续对其进行链式编程.

使用链式编程的好处显而易见了, 相比于函数式编程繁杂的嵌套, 链式编程更加简洁且如同自然语言一般易于阅读.

那么, 考虑在 C++ 中我们应该如何使用链式编程?

链式编程的核心

链式编程的目的在于, 我们可以对对象进行连续的方法调用, 而不是像函数式编程那样, 需要嵌套多层函数调用.

那么这就要求, 对象的这些方法需要返回对象自身(或是其它类型)以实现继续调用.

Talk is cheap, show me the code.

我们定义一个 Person 类如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Person {

int age = 0;

Person SetAge(int age) {
this->age = age;
return *this;
}

Person AddAge(int age) {
this->age += age;
return *this;
}

int GetAge() {
return this->age;
}
}

那么我们可以这样使用:

1
2
3
4
5
6
7
8
9
int main() {
auto age = Person()
.SetAge(10)
.AddAge(5)
.GetAge();
printf("%d\n", age);
return 0;
}
// Output: 15

如此一来我们便实现了一个支持链式调用的 Person

总结

善用链式编程可以大大提升代码的可读性与美观程度

不过这也对类的设计提出了更高的要求

在稍微大型一些的项目中, 可以在多个相关类之间设计支持链式编程的方法, 以实现更加优雅的代码

值得一提的是, 在 C# 的 LINQ 语法中, 支持链式编程的方法往往服务的对象是接口 (例如 IEnumerable), 而不是具体的类, 这对众多库开发者又有什么启示呢?