前言
上一節我們學習了單一職責原則,簡單來說就是各司其職,廚師就專注做好菜,不要跑到前堂做起小二。
但是呢,萬事無一絕對。如果只是小飯店有時候也不是特別嚴格。還是那句話,原則是死的,人是活的。
接下來我們來學習介面隔離原則。
基本介紹
客戶端不應該依賴它不需要的介面,即一個類對另一個類的依賴應該建立在最小的介面上。
怎麼理解呢?
就是說,一個介面擁有的行為應該儘可能的小。
如果說這個介面定義了很多方法,但是呢,我們實現這個介面的時候並不需要這麼多的方法。那麼你就會發現,除了個別幾個你需要的方法實現了,很多不需要的方法也必須得實現了,造成很多空方法的出現。
這是一種很糟糕的設計,這樣做不僅會強制實現本來不該實現的方法,最嚴重的是會給使用者造成假象,即這個實現類擁有介面中所有的行為,結果呼叫方法時卻沒收穫到想要的結果。
案例
案例如下:
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版本以後就可以不需要遵循最小介面原則了?答案是否定了。
即便你不需要實現這個方法,但是在使用者眼中,就會給使用者造成車會飛的假象。
當然,還是那句話,人是活的,規則是死的。很多時候我們並不是說必須百分百按照這種要求來實現我們的程式碼。
當你的程式碼嚴格實現該原則的時候發現,導致程式碼的可閱讀性,可擴充套件性降低。甚至邏輯也複雜了很多。那麼就可以按照具體的情況違背這種原則。
總結
介面隔離原則和職責單一原則有共同性。大家可以多思考一下。
還是那句話慢慢的學,一個一個掌握,才更深刻,貪多嚼不爛。
下一篇我們來學習依賴倒轉原則。