softwareArchitecture

深入淺出介面分割原則 Interface Segregation Principle

這篇文章介紹軟體架構裡面 S.O.L.I.D 中的I (Interface Segregation Principle)

這篇文章中大部分的程式碼 參考自SOLID Principles of Object-Oriented Design and Architecture 以及SOLID Principles: Introducing Software Architecture & Design

定義

No client should be forced to depend on methods it does not use.

就是字面上的意思 你不應該去依賴你根本不會用到的東西

這個原則比較直觀 我們就舉個例子吧

全功能印表機

Alt text

這一是台Xerox WorkCentre 全功能印表機 這台可以

影印 掃描 傳真 等等的功能

來一個介面

interface IMultiFunction
  public void print();

  public void scan();

  public void fax();

  public void copy();
}

非常合理 來個Xerox WorkCentre吧

class XeroxWorkCentre implements IMultiFunction
  @Override
  public void print(){
    // implement print
  }

  @Override
  public void scan(){
    // implement scan
  }

  @Override
  public void fax(){
    // implement fax
  }

  @Override
  public void copy(){
    // implement copy
  }
}

那要是今天來了一個只有傳真功能的傳真機 怎麼辦

class FaxMachine implements IMultiFunction
  @Override
  public void print(){
    
  }

  @Override
  public void scan(){
    
  }
  
  @Override
  public void fax(){
    // implement fax
  }

  @Override
  public void copy(){
    
  }
}

那他對於其他的用不到的功能 就只能一片空白

有什麼大不了的呢

今天有一個想使用FaxMachine的人 他看到你實作了IMultiFunction 就會以為這是個全功能的機器 使用者必須要仔細的去看你的code 看到了print()裡面是一片空白才知道他不能用

有沒有感覺上面那句話依賴感很重 因為這是個不好的設計

Cohesion vs Coupling

我們稍微來看一下這兩個詞的差異

Cohesion: degree to which the various parts of a software component are related

Coupling: level of inter dependency between various software component

Cohesion指的是 一個元件裡面的不同元件的關聯性

Coupling指的是 不同元件裡面的依賴關係強度

我們在講S.O.L.I.D的時候 追求的都是

Aim for high cohesion and loose coupling

就是Cohesion越高越好 Coupling越鬆越好

回到IMultiFunction

這樣看下來 IMultiFunction的cohesion實在不高 更不用說違反了SRP

interface IMultiFunction
  public void print();

  public void scan();

  public void fax();

  public void copy();
}

那該怎麼搞呢

interface IPrint{
  public void print();
}

interface IScan{
  public void scan();
}

interface IFax{
  public void fax();
}

interface ICopy{
  public void copy();
}

不要懷疑 就是這麼簡單

如果你有一個可以影印+掃描的機器 那就實作IPrint跟IScan兩個不同的介面就可以

講起來很簡單很直觀 但好處非常的巨大 使用者不再需要仔細看你怎麼實作

你有實作IPrint 那我就可以呼叫print() 你有實作IScan 那我就可以呼叫scan()

總結

ISP講完了 主要是在說明認識極少化(Least Knowledge Principle)以及模組之間的訊息隱藏

好處如下

1.你只要看這個模組的依賴關係 就可以知道這個模組可以做什麼

2.你只要看這個模組的依賴關係 就可以知道這個模組不可以做什麼

3.迫使你必須要把你的大介面 分離成眾多小介面