版权归原作者所有,如有侵权,请联系我们

[科普中国]-抽象泄漏

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

抽象泄漏”是软件开发时,本应隐藏实现细节的抽象化不可避免地暴露出底层细节与局限性。抽象泄露是棘手的问题,因为抽象化本来目的就是向用户隐藏不必要公开的细节。

历史艾林·约耳·斯波尔斯基于2002年提出了抽象泄露。更早于1992年,Gregor Kiczales描述了不完善的抽象化的一些问题并提出一些解决办法。

抽象泄漏法则斯波尔斯基给出的抽象泄漏法则:

|| ||

对软件开发的影响由于软件开发与运行环境越来越复杂,开发者必须依赖于各种抽象。使得开发者专注于高层次的领域相关的知识与技能,以提高工作效率。但是,抽象泄漏法则指出“可靠”软件的开发者必须了解抽象之下的底层细节。否则一旦出了任何问题,根本不会知道是怎么回事,也不知道如何除错或回复。程序设计工具抽象掉某些东西,但和其他所有抽象机制一样都有漏洞,而唯一能适当处理漏洞的方法,就是弄懂该抽象原理以及所隐藏的东西。所以抽象机制虽然节省了工作的时间,不过学习的时间是省不掉的。

例子TCP/IP协议栈使得软件开发者只需使用可靠传输的TCP协议就能完成网络通信任务,并不需要了解下层的IP协议。不过有时网络会越过抽象机制泄漏出底层问题。例如劣化的网络通信情况会导致丢包现象严重,从而TCP协议之上的应用程序感受到吞吐量与延迟等性能上的起伏变化1。

遍历一个大型二维矩阵数据结构,按照行序或者列序会有巨大的性能差异,这是由于矩阵数据在内存中的存储顺序与CPU cache不命中。即使对于一个汇编程序员知道这些底层细节,并且按照内存中连续存储来遍历这个矩阵数据,仍然会面临着页缺失这样更底层的抽象泄漏。

SQL语言抽象了对数据库的操纵细节。允许数据库程序员只是描述想要做的目标。但是特定的SQL查询可能与其他等价的SQL查询有数千倍的性能差别。有个很有名的例子,在某个SQL服务器用"where a=b and b=c and a=c"来查询,会比用"where a=b and b=c"快上许多,虽然查询的结果是一样的。于是就得跳入更底层用查询规划分析器找出问题,然后想办法加快查询。

网络文件系统如NFS与SMB令用户处理远程机器上的文件如同本地文件。但到远程机器的连结可能会变慢甚至断掉,“远程文件和本地文件一样”的抽象机制出现漏洞了。举个Unix系统管理员曾遇到的例子。如果把使用者的home目录放在用NFS接入的硬盘上(一种抽象机制),使用者建了一个.forward文件把他的电邮全部转发到其他地方(另一种抽象机制)。如果新邮件到来时NFS服务器停掉了,由于找不到.forward文档,邮件并不会被转发出去。这个抽象机制的漏洞就真的会把一些信息丢掉。

ASP.NET网页开发,抽象掉了点击HTML超链接()代码与点击一个按钮的代码的区别。但ASP.NET要隐藏HTML无法通过超链接提交一个图表,这是通过几行JavaScript代码附加了onclick处理这个超链接。但是,如果用户关闭了JavaScript功能,那ASP.NET应用将会出故障。万一ASP应用的程序员不了解ASP.NET抽象掉什么东西,根本不可能知道出了什么问题。

参见抽象反转

依赖反转原则

本质复杂度

模组 (程式设计)

关注点分离

本词条内容贡献者为:

孔祥杰 - 副教授 - 大连理工大学软件学院