闲话说抽象
在计算机领域,我最推崇的一句名言是:「软件开发中遇到的所有问题,都可以通过增加一层抽象而得以解决」(All problems in computer science can be solved by another level of indirection)。
这话不难理解。我举几个例子:
- 操作系统是裸机和应用程序之间的抽象。想想没有操作系统的时代,应用程序开发者需要了解多少硬件细节?
- 虚拟内存是物理内存和应用程序之间的抽象。实地址时代,应用程序各种矮矬穷,要绞尽脑汁地省内存,一不小心还会把整个系统搞崩溃了;有了虚拟内存,乾坤逆转,应用程序一下子变得高富帅起来,还受到各种保护,别人崩溃跟我基本没什么事。
- JVM(或者各种语言的VM,如python 解释器,erlang BEAM等)是操作系统和应用程序间的抽象。写软件的人最希望「撰写一次,到处运行」(write once, run everywhere),加了这一层,跨平台不再是问题。
- 虚拟机是宿主系统(Host OS)和访客系统(Guest OS)的抽象。它直接开启了虚拟化时代和云计算时代。
软件架构中处处可见这样的抽象。大到硬件抽象层 HAL(Hardware Abstract Layer),小到你写的一个API,一个接口,都是抽象的思路:将调用者和被调者隔离开,既屏蔽细节,又提高了灵活性。
生活中的抽象也很多,充电器就是最典型的一个。世界各地的输入电流,电压都各不相同,插口更是千差万别,一个手机在设计上不可能满足所有的插口。那么,我们就在两者之间添加一个适配器 —— 手机充电器。
抽象不光是屏蔽细节和提升系统灵活性那么简单。集装箱将货物和承载货物的工具分离开,大大提高了运输的效率,还增强了安全性。
回到软件开发,我们看看抽象如何提升效率。比如说一个经典的 MVC 应用程序,我要从数据库中读取数据,装入模型(model),并展现到视图(view)中。如果在调用者(模型)和被调者(数据库)中加入抽象,让调用者不知道数据的来源,只要使用特定的接口就能获取数据,那么,我们就可以将数据放入缓存,只有需要的时候才读取数据库,这样应用程序的性能就大大提高了。
道理非常简单,似乎人人都懂,但做起来并不那么简单。知道系统里哪个部分需要动手术加一层抽象,考量的是经验和智慧;如何加这个抽象,考量的是能力。现在人们对集装箱和充电器习以为常,认为那是个连小孩子都懂的简单概念,但如果让你寻找下一个『集装箱』或者『充电器』,你能找得到么?
总结一下,抽象的好处:
- 屏蔽细节
- 提高灵活性
- 增强安全性
- 提升效率