Interface在OO中處于核心地位,針對接口編程更是OOP的核心原則之一,但即使將該原則貫徹到底的COM/CORBA,依然面對大量的依賴、耦合,牽一接口而動全部客戶的修改
另一方面,Hurb Sutter說各種編程范式,包括面向對象,核心都是某種管理依賴性,降低依賴性的技術,那么.Net Attribute, XDoclet, Java Annotation代表的Attribute Oriented Programming在降低依賴性上又前進了多少呢?
以Java Annotation為例,與Java Interface做個對比
1,調用方式
實現Interface的類 | 被Annotation標注的類 |
---|---|
Call by Signature:就像現實生活中的螺絲螺母,插座插頭,必須完全吻合 | Call by Semantics:就像卡西利亞斯被罰下,臨時指定肥羅當守門員一樣,肥羅并不需要實現GateKeeper接口,只需臨時被標記為具有GateKeeper屬性,便可以合法的禁區內手球 |
2,名稱沖突(可看作是對函數簽名的依賴,當然,無論Annotation還是Interface,都不允許存在完全相同的全名)
實現Interface的類 | 被Annotation標注的類 |
---|---|
Yes,無法解決從多個接口繼承來的方法具有相同簽名不同語義的問題 | No,Annotation是類型,不會存在完全相同的全名 |
3,編譯時依賴(對Annotation或Interface的依賴)
Annotation | Interface | ||||
---|---|---|---|---|---|
被Annotation標注的類 | 使用了Annotation的客戶 | 不使用Annotation的客戶 | 實現Interface的類 | 使用Interface的客戶 | 不使用Interface的客戶 |
Yes | Yes | No,只要“被Annotation標注的類”已經被編譯為bytecode,如以jar包的形式存在,那么使用了該類,但沒有用到Annotation的客戶,編譯時不需要依賴Annotation所在的Jar包 | Yes | Yes | Yes,即使客戶沒有用到該類所實現的所有接口,編譯時該類涉及的所有接口的定義必須可見 |
4,運行時依賴(對Annotation或Interface的依賴)
Annotation | Interface | ||||
---|---|---|---|---|---|
被Annotation標注的類 | 使用了Annotation的客戶 | 不使用Annotation的客戶 | 實現Interface的類 | 使用Interface的客戶 | 不使用Interface的客戶 |
No(即使RetentionPolicy是RUNTIME,我的測試中也是不依賴Annotation的,只要客戶不涉及Annotation,但我不確定RUNTIME的真正含義是什么) | Yes | No(其實運行時對Annotation的依賴被轉移到了客戶) | Yes | Yes | Yes |
5,對Annotation或Interface本身更改的依賴
Annotation | Interface | ||||
---|---|---|---|---|---|
被Annotation標注的類 | 使用了Annotation的客戶 | 不使用Annotation的客戶 | 實現Interface的類 | 使用Interface的客戶 | 不使用Interface的客戶 |
Yes | Yes | No | Yes | Yes | No |
6,對“被Annotation標注的類不再被標注”或“實現Interface的類不再實現Interface”這類更改的依賴
Annotation | Interface | ||||
---|---|---|---|---|---|
被Annotation標注的類 | 使用了Annotation的客戶 | 不使用Annotation的客戶 | 實現Interface的類 | 使用Interface的客戶 | 不使用Interface的客戶 |
Yes | No | No | Yes | Yes | No |
總共 5 處被藍色字體標注的地方,也就是Annotation在降低依賴性上優于Interface的 5 個方面,也算更接近于“你不需要為你用不到的東西付出代價”這一語言和庫的設計理念
當然,Annotation有其它的代價,幾個潛在的可能就是“使用方便性”和“性能”