清單 2 中的代碼出現了問題,尤其是它通過一個硬編碼的 SQL 語句直接與一個硬編碼的數據庫進行通信。Yeeesh! 您能夠想像開發人員測試這種 GUI 和相關數據庫的挑戰嗎(順便說一下,測試本應該簡單得像測試一個 Web 頁面一樣)? 倘若對數據庫的任何改動都將 影響到 GUI,那么要考慮修改系統的話會使情況變得更糟。
![]() |
|
現在在腦海中考慮一下使用依賴性倒置原則設計的相同的系統。如圖 2 所示,通過向應用程序添加兩個組件來解除應用程序中的耦合是可能的:這兩個組件分別是一個接口和一個實現:
圖 2. 一個松散耦合的系統

在圖 2 所示的應用程序中,GUI 依賴于一個抽象 —— 一個數據訪問對象或 DAO。DAO 的執行直接依賴于數據庫,但是 GUI 本身并沒有陷入其中。以 DAO 的形式添加一個抽象可以從 GUI 實現將數據庫實現解耦。一個接口會替代數據庫與 GUI 代碼相耦合。清單 3 顯示了該接口。
public interface WidgetDAO { public String getOrderStatus(String widget); //.... } |
GUI 的
ActionListener
代碼引用接口類型 WidgetDAO
(定義在清單 3 中)而不是接口的實際實現。在清單 4 中,GUI 的 getOrderStatus()
方法在本質上指定的是 WidgetDAO
接口:
private String getOrderStatus(String value) {
return dao.getOrderStatus(value);
}
對 GUI 完全隱藏了這個接口的實際實現,因為它是通過一個工廠來請求實現類型的,如清單 5 所示:
private WidgetDAO dao; //... private void initializeDAO() { this.dao = WidgetDAOFactory.manufacture(); } |
注意,清單 5 中的 GUI 中的代碼只引用接口類型 —— GUI 中的任何地方都沒有使用(或導入)接口的實現。這種對實現細節的抽象是靈活性的關鍵:它使您能夠更換實現類型,而完全不會影響到 GUI。
還要注意,清單 5 中的 WidgetDAOFactory
是如何使 GUI 避開 WidgetDAO
類型的創建細節的。這些是工廠的任務,如清單 6 所示:
文章來源于領測軟件測試網 http://www.kjueaiud.com/