件读写指针移回到这个位置来重写这两个值。
结构的设计就决定了算法的实现。这已然是很明显的事。现在所有的.zip 文件都以这种方
式标识着子文件,因此我们已经没有任何办法来修改算法,使结构被重用到新的算法,或者
使其他算法被应用到这个旧的结构。
结构体的设计直接面向存储,正是这种过低的抽象层次使重用性大大地降低。程序、系
统和开发人员被约束在结构的设计与调整之上,而不是关注于现实系统的实现之上。
其三,僵化的类型与僵化的逻辑并存,影响了业务逻辑的表达。
现实生活中,人们并不关心“关注对象”的类型,而只关注于其具体的逻辑。例如人们
在饥饿时只关注“吃”,并不关注于吃的是什么。
在一个子系统的逻辑产生的时候,子系统事实上只关注于逻辑作用于一个该作用的对象,
而并不关注这个对象的构造(如类型)。例如财务人员面对手中的一堆票据,他只关心这些票
据的总金额是多少,因此“求总计”的子系统最直接的实现方法,就应当类似于“财务人员
手执一个计算器(或算盘)”:计算系统内部如何处理小数与整数,那是靠另外的一套法则去
保障的,而最好不要直接地与原始数据(票据)关联起来。
泛型运算解决的正是这样的问题。在一个强类型系统中,泛型系统像一台计算器或算
盘一样,用独立的逻辑(例如 C 语言中模板在编译时生成代码)去应付各种数据类型上的
运算法则。而在业务逻辑层面,开发人员只需要将来自输入的原始数据(例如票据)累加
即可。
/**
* programming language: C
* 示例 1:处理确定类型值的累加函数
*/
long add_values(long a, long b) {
return (a + b);
}
/**
* programming language: C++
* 示例 2:处理不同类型值的累加函数, 通过模板(泛型)来解决强类型问题的示例
*/
#include <iostream.h>
template <class type1, class type2> type1 add_values(type1 a, type2 b) {
return (a + b);
}
long add_values(long a, int b);
double add_values(double a, long b);
/**
* call demo
* v1, v2, v3 模拟输入的可变类型的原始数据
*/
void main(void) {
long v1 = 1200L;
int v2 = 1100;
double v3 = 100.0 / 3;
cout << "Value: " << add_values(v3, add_values(v1, v2)) << endl;
}
强类型与泛型出现的真正原因,仍然是因为“结构体”是面向存储进行的数据抽象。只
有抽象层次更高一些,抽象不会影响到存储本身时,这个矛盾才会被真正解决。
3、“面向对象语言”是突破吗?
在上一节中,我有意地将“结构化的疑难”归结为由“抽象层次过低”所引发的三点,