抽象泄漏

維基百科,自由的百科全書

抽象泄漏」是軟件開發時,本應隱藏實現細節的抽象化不可避免地暴露出底層細節與局限性。抽象泄露是棘手的問題,因為抽象化本來目的就是向用戶隱藏不必要公開的細節。[1]

歷史[編輯]

艾林·約耳·斯波爾斯基於2002年提出了抽象泄露。[2]更早於1992年,Gregor Kiczales英語Gregor Kiczales描述了不完善的抽象化的一些問題並提出一些解決辦法。[3]

抽象泄漏法則[編輯]

斯波爾斯基給出的抽象泄漏法則:

對軟件開發的影響[編輯]

由於軟件開發與運行環境越來越複雜,開發者必須依賴於各種抽象。使得開發者專注於高層次的領域相關的知識與技能,以提高工作效率。但是,抽象泄漏法則指出「可靠」軟件的開發者必須了解抽象之下的底層細節。否則一旦出了任何問題,根本不會知道是怎麼回事,也不知道如何除錯或回復。程序設計工具抽象掉某些東西,但和其他所有抽象機制一樣都有漏洞,而唯一能適當處理漏洞的方法,就是弄懂該抽象原理以及所隱藏的東西。所以抽象機制雖然節省了工作的時間,不過學習的時間是省不掉的。

例子[編輯]

  • TCP/IP協議棧使得軟件開發者只需使用可靠傳輸的TCP協議就能完成網絡通信任務,並不需要了解下層的IP協議。不過有時網絡會越過抽象機制泄漏出底層問題。例如劣化的網絡通信情況會導致丟包現象嚴重,從而TCP協議之上的應用程序感受到吞吐量與延遲等性能上的起伏變化。
  • 遍歷一個大型二維矩陣數據結構,按照行序或者列序會有巨大的性能差異,這是由於矩陣數據在內存中的存儲順序與CPU cache不命中。即使對於一個匯編程序員知道這些底層細節,並且按照內存中連續存儲來遍歷這個矩陣數據,仍然會面臨着頁缺失這樣更底層的抽象泄漏。
  • SQL語言抽象了對數據庫的操縱細節。允許數據庫程序員只是描述想要做的目標。但是特定的SQL查詢可能與其他等價的SQL查詢有數千倍的性能差別。有個很有名的例子,在某個SQL服務器用"where a=b and b=c and a=c"來查詢,會比用"where a=b and b=c"快上許多,雖然查詢的結果是一樣的。於是就得跳入更底層用查詢規劃分析器找出問題,然後想辦法加快查詢。
  • 網絡文件系統如NFSSMB令用戶處理遠程機器上的文件如同本地文件。但到遠程機器的連結可能會變慢甚至斷掉,「遠程文件和本地文件一樣」的抽象機制出現漏洞了。舉個Unix系統管理員曾遇到的例子。如果把使用者的home目錄放在用NFS接入的硬盤上(一種抽象機制),使用者建了一個.forward文件把他的電郵全部轉發到其他地方(另一種抽象機制)。如果新郵件到來時NFS服務器停掉了,由於找不到.forward文檔,郵件並不會被轉發出去。這個抽象機制的漏洞就真的會把一些信息丟掉。
  • ASP.NET網頁開發,抽象掉了點擊HTML超鏈接(<a>)代碼與點擊一個按鈕的代碼的區別。但ASP.NET要隱藏HTML無法通過超鏈接提交一個圖表,這是通過幾行JavaScript代碼附加了onclick處理這個超鏈接。但是,如果用戶關閉了JavaScript功能,那ASP.NET應用將會出故障。萬一ASP應用的程序員不了解ASP.NET抽象掉什麼東西,根本不可能知道出了什麼問題。

參見[編輯]

參考資料[編輯]

  1. ^ Barbara Liskov, John Guttag著,裘健譯:《程序開發原理:抽象、規格與面性對象設計》,北京:電子工業出版社,2006年10月:第3-5頁。
  2. ^ Spolsky, Joel. The Law of Leaky Abstractions. 2002 [2010-09-22]. (原始內容存檔於2016-11-20). 
  3. ^ Kiczales, Gregor. Towards a New Model of Abstraction in the Engineering of Software (PDF). 1992 [2010-02-03]. (原始內容 (PDF)存檔於2011-06-04).  - a paper by Gregor Kiczales that describes the problem of imperfect abstractions and suggests a programming model for coping with them.