最近在看一本書 Java與模式,裏面提了一句不建議使用常量接口,甚至舉了個java源碼的反例,
蛋疼的是沒有說爲什麼?
查了網上一圈發現他們也是知道怎麼做而不知道爲什麼這麼做。
然後我只能找谷歌了,翻譯後,我把自己理解外加總結的放在下面。
第一
常量類應該是final,不變的,而接口裏的參數是final,也是不變的。
那麼,看起來接口是放常量沒有一定問題,還省去了final的輸入,非常的合適。
但是,類是隻能單繼承的,接口是允許多實現的。
要是類實現的多個接口出現重名的常量,會報錯,必須要在實現類明確常量用的是哪個接口的。
雖然這可以說是架構師設計的問題,但是,架構師這麼做就違反了依賴倒轉原則,這玩意就不細說了。
第二
如果某個實現了常量接口的類被修改不再需要常量了,也會因爲序列化兼容原因不得不保持該實現,而且非final類實現常量接口會導致所有子類被污染。
這個應該很少人遇到過,不過這是 Effective Java 裏面說的。
具體的理解就是,能被序列化的一定是數據,
那麼突然改了數據結構,可能導致老版的數據無法被反序列化,而新版的數據會有冗雜的數據,
要是折騰個幾次,網絡傳輸協議 這個無法通過時間或者空間提升的玩意就能逼死你了。
Effective Java 作者 大佬的原話
According to Joshua Bloch, author of "Effective Java": The constant interface pattern is a poor use of interfaces. That a class uses some constants internally is an implementation detail. Implementing a constant interface causes this implementation detail to leak into the class's exported API. It is of no consequence to the users of a class that the class implements a constant interface. In fact, it may even confuse them. Worse, it represents a commitment: if in a future release the class is modified so that it no longer needs to use the constants, it still must implement the interface to ensure binary compatibility. If a nonfinal class implements a constant interface, all of its subclasses will have their namespaces polluted by the constants in the interface.
第三
基於數據只暴露給相應的類的原則,一個類實現一個常量接口,可能只需要其中幾個常量,而得到了更多無用的常量,
所以,使用常量接口的時候都是
import static const.valueAAA
那此時和常量類有區別嗎?
總結
接口是定義類型的,而不應該用於導出常量。常量接口不建議使用,應使用常量類。