接口隔離原則(Interface Segregation Principle,ISP)要求程序員儘可能將臃腫龐大的接口拆分紅更小的和更具體的接口,讓接口中只包含客戶感興趣的方法。html
與上一篇介紹的單一職責原則相似,接口隔離原則一樣是爲了提升類的內聚性、下降它們之間的耦合性,都是面向對象三個基本特徵中的「封裝」思想的體現。程序員
但二者也存在不一樣之處:框架
單一職責 | 接口隔離 | |
做用目標 | 類 | 接口 |
範圍級別 | 實現細節 | 總體框架 |
側重方面 | 職責劃分 | 接口依賴 |
這裏重點說一下「接口依賴」與「接口實現」的區別:ide
依賴(Dependency)關係是一種使用關係,它是對象之間耦合度最弱的一種關聯方式,是臨時性的關聯。this
在代碼中,某個類的方法經過局部變量、方法的參數或者對靜態方法的調用來訪問另外一個類(被依賴類)中的某些方法來完成一些職責。spa
圖形表示:依賴關係使用虛線箭頭表示,使用類指向被依賴的類。(下圖左側的線)code
實現(Realization)關係是接口與實現類之間的關係。在這種關係中,類實現了接口,類中的操做實現了接口中所聲明的全部的抽象操做。htm
圖形表示:實現關係使用帶空心三角箭頭的虛線來表示,箭頭從實現類指向接口。(下圖右側的線)對象
如上面的UML類圖所示:blog
下面以代碼的方式說明二者的區別。
1 package asen.yang; 2 public interface IAction { 3 public void eat(); 4 5 public void sleep(); 6 7 public void beatDD(); 8 } 9 10 public class CommonAction implements IAction { 11 12 @Override 13 public void eat() { 14 System.out.println("吃飯"); 15 } 16 17 @Override 18 public void sleep() { 19 System.out.println("睡覺"); 20 } 21 22 @Override 23 public void beatDD() { 24 System.out.println("打豆豆"); 25 } 26 } 27 28 public class People { 29 private String Name; 30 31 public People(String Name) { 32 this.Name = Name; 33 } 34 35 protected void Action() { 36 IAction action = new CommonAction(); 37 System.out.println("我是" + Name); 38 System.out.println("個人愛好有:"); 39 action.eat(); 40 action.sleep(); 41 action.beatDD(); 42 } 43 } 44 45 public class ISP_Demo { 46 public static void main(String[] args) { 47 People p = new People("小明"); 48 p.Action(); 49 } 50 }
Action類"實現"了IAction接口,所以要實現接口中所聲明的全部方法。
而People類「依賴」IAction接口,在People類的Action()方法中,使用了IAction類型的變量action。
本原則所側重的就是第二種形式的接口依賴關係。
假如除了人這個類別以外,還有一個狗類,而狗並不會打豆豆,只會吃飯睡覺。依照本原則,就應該將IAction拆分。
UML類圖以下:
對應的代碼能夠重構爲:
1 package asen.yang; 2 public interface ILowAction { 3 public void eat(); 4 public void sleep(); 5 } 6 7 public interface IHighAction{ 8 public void beatDD(); 9 } 10 11 public class LowAction implements ILowAction { 12 @Override 13 public void eat() { 14 System.out.println("吃飯"); 15 } 16 17 @Override 18 public void sleep() { 19 System.out.println("睡覺"); 20 } 21 } 22 23 public class HighAction implements IHighAction{ 24 25 @Override 26 public void beatDD() { 27 System.out.println("打豆豆"); 28 } 29 } 30 31 public class People { 32 private String Name; 33 34 public People(String Name) { 35 this.Name = Name; 36 } 37 38 public void Action() { 39 ILowAction lowaction = new LowAction(); 40 System.out.println("我是" + Name); 41 System.out.println("個人低級愛好有:"); 42 lowaction.eat(); 43 lowaction.sleep(); 44 45 IHighAction highaction = new HighAction(); 46 System.out.println("個人高級愛好有:"); 47 highaction.beatDD(); 48 } 49 } 50 51 public class Dog { 52 private String Name; 53 54 public Dog(String Name) { 55 this.Name = Name; 56 } 57 58 public void Action() { 59 ILowAction lowaction = new LowAction(); 60 System.out.println("我是" + Name); 61 System.out.println("個人愛好有:"); 62 lowaction.eat(); 63 lowaction.sleep(); 64 } 65 } 66 67 public class ISP_Demo { 68 public static void main(String[] args) { 69 People p = new People("小明"); 70 p.Action(); 71 72 Dog d = new Dog("汪汪"); 73 d.Action(); 74 } 75 }
將"吃飯"、"睡覺"這兩種人與狗都有的共性的行爲,單獨封裝在一個接口中。而將只有人具備的"打豆豆"這個行爲,封裝在單獨的接口中。
這就是接口隔離原則的最直接體現。