实现列表管道结构- -
列表(list)的管道(pipe)结构是这样一种结构:一个列表经过N道工序加工处理,最终结果仍然是一个列表,且结果元素与初始元素之间有某种对应关系。通常为了保证管道畅通和灵活,还要求各工序加工之后,列表中元素对象不变,仅仅改变各元素状态。例如一个典型的管道处理:
List<Person> ===> (年龄+1) ===> (工资+1000) ===> List<Person>
直观的,管道就是一组映射(map)操作。所以上述管道可以如此实现:
Object init = getPersonList();
Object result = new Map().evaluate(new AddSalary(), init);
result = new Map().evaluate(new AddAge(), init);
再需要其他操作,也逐个往上映射便是。但还有一种理解方式,可以将管道看作一个累加(accumulate,或者Python中的reduce),将一组操作挨个映射到初始的列表上。所以上述管道也可以如此实现:
Object init = getPersonList();
Object functions = new ArrayList() {
{
add(0, new AddSalary());
add(0, new AddAge());
}
};
Object result = new Accumulate().evaluate(new Map(), init, functions);
两种实现复杂度也差不多,总之都比原始的、一次次循环的做法要好。第二种实现的关键在于:映射(Map)本身也是一个二元函数(BinaryFunction),可以将它组合到accumulate里面,此时accumulate处理的列表便是“管道中的各个操作”。
看SICP速度奇慢,刚看到3.3节。这里有一个模拟数字电路的例子。为什么电子工程师的复用做得这么好,而我们软件工程师就做不到呢?也许是因为电子元件没有状态的缘故吧?