盡管防御性編程有效地保證了方法的輸入條件,但如果在一系列方法中使用它,不免過于重復。熟悉面向方面編程(或 AOP)的人們會把它認為是橫切關注點,這意味著防御性編程技術橫跨了代碼庫。許多不同的對象都采用這些語法,盡管從純面向對象的觀點來看這些語法跟對象毫不相關。
而且,橫切關注點開始滲入到契約式設計(DBC)的概念中。DBC 是這樣一項技術,它通過在組件的接口顯式地陳述每個組件應有的功能和客戶機的期望值來確保系統中所有的組件完成它們應盡的職責。從 DBC 的角度講,組件應有的功能被認為是后置條件,本質上就是組件的責任,而客戶機的期望值則普遍被認為是前置條件。另外,在純 DBC 術語中,遵循 DBC 規則的類針對其將維護的內部一致性與外部世界有一個契約,即人所共知的類不變式。
契約式設計
我在以前的一篇關于用 Nice 編程的文章中介紹過 DBC 的概念,Nice 是一門與 JRE 兼容的面向對象編程語言,它的特點是側重于模塊性、可表達性和安全性。有趣的是,Nice 并入了功能性開發技術,其中包括了一些在面向方面編程中的技術。功能性開發使得為方法指定前置條件和后置條件成為可能。
盡管 Nice 支持 DBC,但它與 Java™ 語言完全不同,因而很難將其用于開發。幸運的是,很多針對 Java 語言的庫也都為 DBC 提供了方便。每個庫都有其優點和缺點,每個庫在 DBC 內針對 Java 語言進行構建的方法也不同;但最近的一些新特性大都利用了 AOP 來更多地將 DBC 關注點包括進來,這些關注點基本上就相當于方法的包裝器。
前置條件在包裝過的方法執行前擊發,后置條件在該方法完成后擊發。使用 AOP 構建 DBC 結構的一個好處(請不要同該語言本身相混淆。┦牵嚎梢栽诓恍枰 DBC 關注點的環境中將這些結構關掉(就像斷言能被關掉一樣)。以橫切的方式對待安全性關注點的真正妙處是:可以有效地重用 這些關注點。眾所周知,重用是面向對象編程的一個基本原則。AOP 如此完美地補充了 OOP 難道不是一件極好的事情嗎?