面向對象設計模式原則02 接口隔離原則(ISP)

接口隔離原則(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 }

將"吃飯"、"睡覺"這兩種人與狗都有的共性的行爲,單獨封裝在一個接口中。而將只有人具備的"打豆豆"這個行爲,封裝在單獨的接口中。

這就是接口隔離原則的最直接體現。

相關文章
相關標籤/搜索