概要
Clients should not be forced to depend upon interfaces that they do not use.
不能強迫用戶去依賴那些他們不使用的接口。換句話說,使用多個專門的接口比使用單一的總接口總要好。
它包含了2層意思:
- 接口的設計原則:接口的設計應該遵循最小接口原則,不要把用戶不使用的方法塞進同一個接口里。
如果一個接口的方法沒有被使用到,則說明該接口過胖,應該將其分割成幾個功能專一的接口。
- 接口的依賴(繼承)原則:如果一個接口a依賴(繼承)另一個接口b,則接口a相當于繼承了接口b的方法,那么繼承了接口b后的接口a也應該遵循上述原則:不應該包含用戶不使用的方法。
反之,則說明接口a被b給污染了,應該重新設計它們的關系。
如果用戶被迫依賴他們不使用的接口,當接口發生改變時,他們也不得不跟著改變。換而言之,一個用戶依賴了未使用但被其他用戶使用的接口,當其他用戶修改該接口時,依賴該接口的所有用戶都將受到影響。這顯然違反了
開閉原則,也不是我們所期望的。
下面我們舉例說明怎么設計接口或類之間的關系,使其不違反ISP原則。
假如有一個Door,有lock,unlock功能,另外,可以在Door上安裝一個Alarm而使其具有報警功能。用戶可以選擇一般的Door,也可以選擇具有報警功能的Door。
有以下幾種設計方法:
ISP原則的違反例:
方法一:
在Door接口里定義所有的方法。圖:

但這樣一來,依賴Door接口的CommonDoor卻不得不實現未使用的alarm()方法。違反了ISP原則。
方法二:
在Alarm接口定義alarm方法,在Door接口定義lock,unlock方法,Door接口繼承Alarm接口。

跟方法一一樣,依賴Door接口的CommonDoor卻不得不實現未使用的alarm()方法。違反了ISP原則。
遵循ISP原則的例:
方法三:通過多重繼承實現

在Alarm接口定義alarm方法,在Door接口定義lock,unlock方法。接口之間無繼承關系。CommonDoor實現Door接口,
AlarmDoor有2種實現方案:
1),同時實現Door和Alarm接口。
2),繼承CommonDoor,并實現Alarm接口。該方案是繼承方式的
Adapter設計模式的實現。
第2)種方案更具有實用性。
這種設計遵循了ISP設計原則。
方法四:通過委讓實現

這種方法其實是委讓方式的Adapter設計模式的實現。
在這種方法里,AlarmDoor實現了Alarm接口,同時把功能lock和unlock委讓給CommonDoor對象完成。
這種設計遵循了ISP設計原則。
小結
Interface Segregation Principle (ISP)從對接口的使用上為我們對接口抽象的顆粒度建立了判斷基準:在為系統設計接口的時候,使用多個專門的接口代替單一的胖接口。
posted on 2009-03-28 14:17
chunkyo 閱讀(616)
評論(0) 編輯 收藏 所屬分類:
系統設計和設計模式