深入浅出设计模式_深入浅出设计模式03接口隔离原则
本文作者:開課吧寂然
圖文編輯:開三金
大家好~,我是寂然~,本節課呢,我來給大家介紹設計模式原則之接口隔離原則。
話不多說,我們直接進入正題,老規矩,首先帶大家了解一下接口隔離原則的官方定義,并作一個解釋,然后我們通過案例代碼來具體分析。
官方定義
接口隔離原則(Interface ?Segregation Principle),又稱為ISP原則,官方定義為:
1.?Clients?should?not?be?forced?to?depend?upon?interfaces?that?they?don’t?use.? ???(客戶端不應該依賴它不需要的接口) 2.?The?dependency?of?one?class?to?another?one?should?depend?on?the?smallest?possible?interface.?(類間的依賴關系應該建立在最小的接口上)
基本介紹
其實通俗來理解就是,不要在一個接口里面放很多的方法,這樣會顯得這個類很臃腫不堪。
接口應該盡量細化,一個接口對應一個功能模塊,同時接口里面的方法應該盡可能的少,使接口更加輕便靈活。
案例演示 - 市場風云
為了讓大家更好的理解接口隔離原則,我們通過一個案例來詳細解析。
假設有這樣一個案例場景,現在有一個接口knife,給定他有三個能力,可以切蘋果,切番茄,切土豆。
兩個類張廚師,李廚師分別具有這些能力,有一個水果店類,假設是需要張師傅來切蘋果和切番茄,而另一個蔬菜店類需要李師傅來切番茄和切土豆。
OK,明確了需求之后,那相關的基本定義代碼如下圖所示
// 定義接口knifeinterface Knife { //切蘋果的能力 void cutApple(); //切番茄的能力 void cutTomato(); //切土豆的能力 void cutPotato();}//張廚師類class CookZhang implements Knife { @Override public void cutApple() { System.out.println("張廚師正在切蘋果"); } @Override public void cutTomato() { System.out.println("張廚師正在切番茄"); } @Override public void cutPotato() { System.out.println("張廚師正在切土豆"); }}//李廚師類class CookLi implements Knife { @Override public void cutApple() { System.out.println("李廚師正在切蘋果"); } @Override public void cutTomato() { System.out.println("李廚師正在切番茄"); } @Override public void cutPotato() { System.out.println("李廚師正在切土豆"); }}上面這段代碼相信大家并不陌生,將基本的定義好之后,那我們接著往下走,既然有一個水果店類,假設是需要張師傅來切蘋果和切番茄,蔬菜店類需要李師傅來切番茄和切土豆。
那我們可以是這樣一個思路,在水果店類里,定義方法,將接口類型作為參數傳入,調用方法則傳入接口的實現類張廚師類。
即水果店類通過接口來依賴或者說使用張廚師類,從而達到上面的需求,OK,按照這個思路,相應代碼如下圖所示
//水果店類class FruitShop { // 將接口類型作為參數傳入 public void cutApple(Knife knife) { knife.cutApple(); } public void cutTomato(Knife knife) { knife.cutTomato(); }}//蔬菜店類class VegetableShop { public void cutTomato(Knife knife) { knife.cutTomato(); } public void cutPotato(Knife knife) { knife.cutPotato(); }}//簡易測試代碼示例public class SegregationDemo { public static void main(String[] args) { new FruitShop().cutApple(new Cookzhang()); //打印結果:張廚師正在切蘋果 new VegetableShop().cutPotato(new CookLi()); //打印結果:李廚師正在切土豆 }}案例分析
OK,我們用上面的代碼實現了這個簡易案例,那接下來,我們就來分析一下,為了便于大家理解,我把對應的UML類圖展示出來,如下圖所示、當然,有關UML類圖詳細的知識會在后面和大家一一見面,不要著急哈。
OK,那么大家來看上面的類圖,現在需求里,類FruitShop通過接口Kinfe會依賴或者說使用CookZhang。
但是FruitShop里面卻只會用到CookZhang其中的兩個方法,同樣,類VegetableShop也是如此,換句話說,廚師CookZhang 業務上需要兩種切割的能力,就要實現接口 Kinfe,但是Kinfe對于CookZhang來說不是最小接口。
那么類 CookZhang 就必須去實現他們不需要的方法,對吧,上面的案例中 CookZhang 雖然用不到,但是也實現了切土豆的方法,同樣對于CookLi而言,也是這樣。
那么這時,大家回顧一下上面提到的接口隔離原則的定義,類間的依賴關系應該建立在最小的接口上,顯然,上面的寫法雖然可以實現需求,但是Kinfe對于CookZhang來說不是最小接口,違反了接口隔離原則。
解決方案
那到這里有小伙伴就會問了,既然上面的情況違反了接口隔離原則,那按照隔離原則,代碼上應當怎樣處理呢?
那既然接口隔離原則建議 類間的依賴關系應該建立在最小的接口上,那我們不妨將接口 Kinfe 拆分為獨立的幾個接口(這里我們拆分成 3 個接口),類 FruitShop 和類 VegetableShop 分別與他們需要的接口建立依賴關系。
按照這種思路,代碼示例如下圖所示:
// 將Knife拆分為三個接口interface AppleKnife { //切蘋果的能力 void cutApple();}interface TomatoKnife { //切番茄的能力 void cutTomato();}interface PotatoKnife { //切土豆的能力 void cutPotato();}//張廚師類class CookZhang implements AppleKnife,TomatoKnife { @Override public void cutApple() { System.out.println("張廚師正在切蘋果"); } @Override public void cutTomato() { System.out.println("張廚師正在切番茄"); }}//李廚師類class CookLi implements PotatoKnife,TomatoKnife { @Override public void cutTomato() { System.out.println("李廚師正在切番茄"); } @Override public void cutPotato() { System.out.println("李廚師正在切土豆"); }}按照第二種方案,我們將接口 Kinfe拆分為三個接口,張廚師需要切蘋果和切番茄兩種能力,就實現AppleKnife,TomatoKnife兩個接口即可,同樣,水果店的代碼示例如下:
//水果店類class FruitShop { public void cutApple(AppleKnife knife) { knife.cutApple(); } public void cutTomato(TomatoKnife knife) { knife.cutTomato(); }}//蔬菜店類class VegetableShop { public void cutTomato(TomatoKnife knife) { knife.cutTomato(); } public void cutPotato(PotatoKnife knife) { knife.cutPotato(); }}解決方案對應的UML類圖,如下圖所示:
案例總結
OK,那我們的代碼改造完成,現行的代碼就符合了接口隔離原則,經過這個案例,其實說白了,接口隔離原則就是當我一個類通過接口依賴(使用)另一個類的時候,要保證依賴的該接口是最小的。
接口里面有方法用不到的,就進行隔離,而隔離的做法就是,就對原來接口進行拆分,拆分為最小粒度,來避免耦合。
接口隔離原則相對來說是比較簡單的,但是呢,要給大家點出來,其實很多小伙伴實際開發中,所寫的代碼或多或少都符合設計原則而不自知。
現在一條一條明確出來,后面在寫代碼的過程中小伙伴們就會有意的去遵守這些看似簡單卻很重要的設計模式原則,從而降低耦合,去提高代碼的質量。
與單一職責原則對比
或許看到接口隔離原則這樣的定義很多人會覺得和單一職責原則很像,但是這兩個原則還是有著很鮮明的區別。
接口隔離原則和單一職責原則的審視角度是不同的,單一職責原則要求類和接口職責單一,注重的是職責,是業務邏輯上的劃分,而接口隔離原則要求方法要盡可能的少,是在接口設計上的考慮。
例如一個接口的職責包含10個方法,這10個方法都放在一個接口中,并且提供給多個模塊訪問,各個模塊按照規定的權限來訪問,并規定了“不使用的方法不能訪問”。
這樣的設計是不符合接口隔離原則的,接口隔離原則要求“盡量使用多個專門的接口”,這里專門的接口就是指提供給每個模塊的都應該是單一接口(即每一個模塊對應一個接口),而不是建立一個龐大臃腫的接口來容納所有的客戶端訪問。
**當然,根據接口隔離原則拆分接口時,首先必須滿足單一職責原則**
下節預告
OK,下一節,我們正式進入設計模式原則之依賴倒轉原則的學習,我會為大家用多個案例分析,來解讀設計模式—原則之依賴倒轉原則。
以及它的注意事項和細節,最后,希望大家在學習的過程中,能夠感覺到設計模式的有趣之處,高效而愉快的學習,那我們下期見~
掃碼關注,領取Java學習圖鑒
↓ ↓ ↓
你“在看”我嗎?
總結
以上是生活随笔為你收集整理的深入浅出设计模式_深入浅出设计模式03接口隔离原则的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 人工智能论坛_浙江大学人工智能论坛在北京
- 下一篇: 数字货币交易所源码_(数字货币交易所科普