前言
上一節我們學習了單一職責原則,簡單來說就是各司其職,廚師就專注做好菜,不要跑到前堂做起小二。
但是呢,萬事無一絕對。如果只是小飯店有時候也不是特別嚴格。還是那句話,原則是死的,人是活的。
接下來我們來學習接口隔離原則。
基本介紹
客戶端不應該依賴它不需要的接口,即一個類對另一個類的依賴應該建立在最小的接口上。
怎么理解呢?
就是說,一個接口擁有的行為應該盡可能的小。
如果說這個接口定義了很多方法,但是呢,我們實現這個接口的時候並不需要這么多的方法。那么你就會發現,除了個別幾個你需要的方法實現了,很多不需要的方法也必須得實現了,造成很多空方法的出現。
這是一種很糟糕的設計,這樣做不僅會強制實現本來不該實現的方法,最嚴重的是會給使用者造成假象,即這個實現類擁有接口中所有的行為,結果調用方法時卻沒收獲到想要的結果。
案例
案例如下:
public interface Car {
void run();
void fly();
void appearance();
}
public class Audi implements Car {
public static void main(String args[]){
Audi audi = new Audi();
audi.run();
audi.appearance();
audi.fly();
}
@Override
public void appearance() {
System.out.println("我奧迪有炫酷的車燈");
}
@Override
public void run() {
System.out.println("我不光能跑,我還跑的很快");
}
@Override
public void fly() {
}
}
上訴代碼輸出結果
我不光能跑,我還跑的很快
我奧迪有炫酷的車燈
上訴代碼中的接口Car就沒有遵循最小接口原則。因為這個接口定義了一個並不屬於Car的方法fly()。你在實現這個接口的時候你也必須重寫fly()方法。
但是呢,車並沒有這個功能,所以大部分情況下你會將這個方法重寫了但是里面是空方法。
首先代碼不簡潔。其次當某個人調用該類方法的時候,就會給使用者造成車會飛的假象。
default關鍵字
上述代碼在JDK1.8版本以后還能能寫成這種形式
public interface Car {
default void run(){
System.out.println("我能跑");
}
default void fly(){
System.out.println(("我不能飛"));
}
void appearance();
}
public class Audi implements Car {
public static void main(String args[]){
Audi audi = new Audi();
audi.run(); //我不光能跑,我還跑的很快
audi.appearance(); //我有炫酷的車燈
audi.fly(); //我不能飛
}
@Override
public void appearance() {
System.out.println("我有炫酷的車燈");
}
@Override
public void run() {
System.out.println("我不光能跑,我還跑的很快");
}
}
在jdk1.8以后提供了default關鍵字,這個關鍵字的出現讓接口能夠有默認的實現方式。
比如Car接口的的run()方法和fly()方法實現了default關鍵字,那么就能直接在接口當中把這個方法給實現了。
當某個類實現了這個接口的時候,就不需要強制重寫該方法。
有人就會問了,是不是在1.8版本以后就可以不需要遵循最小接口原則了?答案是否定了。
即便你不需要實現這個方法,但是在使用者眼中,就會給使用者造成車會飛的假象。
當然,還是那句話,人是活的,規則是死的。很多時候我們並不是說必須百分百按照這種要求來實現我們的代碼。
當你的代碼嚴格實現該原則的時候發現,導致代碼的可閱讀性,可擴展性降低。甚至邏輯也復雜了很多。那么就可以按照具體的情況違背這種原則。
總結
接口隔離原則和職責單一原則有共同性。大家可以多思考一下。
還是那句話慢慢的學,一個一個掌握,才更深刻,貪多嚼不爛。
下一篇我們來學習依賴倒轉原則。