为什么会把这两个看起来没有关系的问题拿到一起呢? 因为,我认为两个系统的设计者在设计系统的时候面临着同样的问题。
对于Linux操作系统设计者而言,他/她面临怎样使Linux支持所有存在的文件系统(ext2, ext3, FAT32, msdos等)的问题。它希望做到:从操作系统内部看,它希望看到的所有文件系统都是一样(即:它不关心连接的什么文件系统或者叫做跨文件系统)。Linux定义了一套文件系统接口,这套接口定义了文件系统所具有的属性和可以执行的操作。而对于具体的文件系统,如:fat32,ext2等,Linux为每一种文件系统提供一个符合以上接口的实现。由具体的这个实现来负责具体的文件系统的操作。如果您发明了一种新的文件系统,比方叫做FlyFile System。如果你希望Linux支持这套文件系统,只需要编写一个符合Linux规定的接口的实现程序就可以了。
对于Java系统的设计者,他/她面临着怎么样支持多种数据库(Oracle, Sybase, MySQL, IBM DB2等)的问题。它希望做到:从访问数据库的Java程序内部看,它希望访问数据库的方法都是一样的(即:它不关心连接什么数据库或者叫做跨数据库平台)。Java设计者同样为访问数据库定义了一套接口叫做JDBC。这套接口定义了Java程序怎样访问数据库。而对于具体的数据库系统,如:Oracle,Sybase等,各个厂商自己为自己的数据库提供一套符合以上接口的实现。由这个具体的实现来负责具体对数据的数据库操作。同样,如果您自己现在设计了一个新型的叫做SuperManDB的数据库,希望能够被Java系统通过JDBC来访问,您需要编写一个符合JDBC接口的实现。
虽然两个系统使用的实现语言不一样(Linux使用C编写,而JDBC是用于Java系统),但是思想完全一样:提供一个抽象层,然后不同的具体系统提供具体实现。但是做到这一点并不容易,比如:真的能够提供一个抽象层,来覆盖操作所有文件系统或者数据库系统的接口吗? 因为各个具体系统(文件系统或者数据库系统)的设计者想法是不一样的。我认为这个是一个去伪存真的过程,需要设计师花发功夫来分析设计每一个细节,这是一个优秀设计师体现设计水平的地方。
我的失败例子:
同样的一个应用系统,我们想在两个客户使用,但是因为每一个客户都有自己想要的和不想要的。后来系统中充满了类似
if(customer==1) then{
//do something like 1
}else if(customer == 2){
//do something like 2
}
的代码,痛苦不堪。虽然应用在同一个领域,同一个问题上,我们真的能够使用同样的方法来满足不同用户的需要吗? 我觉得很难有答案。同行们,我想大家都有体会,同样是发票管理,这个用户希望这样,那个用户希望那样,怎么处理这个问题?有时候也许为每一个用户开发一个程序是不得已的最终选择。
实例:开放源码系统slide
Slide是一个内容管理系统,需要存储的信息有:文件本身,与文件相关的信息比如文件名、文件大小,索引信息等。 因为文件系统,数据库系统存储各有各擅长的,用户可以根据需要来配置Slide:
1.用文件系统存储文件本身,而用数据库存储文件相关信息(MetaData)和索引信息。
2.全部使用文件系统存储所有信息。
3.完全使用数据系统存储所有信息。
Slide内部提供一个存储抽象层,和具体的存储实现(文件存储实现,Oracle数据库存储实现,MySQL数据库存储实现),用户通过配置文件来根据需要(性能,备份方案)进行配置。