依賴反轉原則

Prerequisites:

概念

英文Dependence Inversion Principle,

Abstractions should not depend on details. Details should depend on abstractions.

依賴抽象,不要依賴具體類別。

這裡的抽象包括介面,因為介面中都是抽象方法。

也跟之前提到「寫程式是針對抽象、介面而寫,而不是針對實踐方式(具體類別)而寫」,是一樣的意思。

未優化前程式碼

以下程式碼,Person收到e-mail訊息並把訊息顯示出來。

1
2
3
4
5
6
7
8
9
10
11
class Email {
  void getInfo() {
    System.out.println("e-mail");
  }
}

class Person {
  void receive(Email email) {
    email.getInfo();
  }
}

main主程式

1
2
3
4
5
6
public class Test {
  public static void main(String[] args) {
    Person person = new Person();
    person.receive(new Email());
  }
}

優化思維

請問,若今天要收到Line、收到手機簡訊、收到FB的Message請問要怎麼做?是改成如下的方式嗎?那如果有100個通訊軟體,要一直寫100個receive()方法?100個參數?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Person {
  void receive(Email email) {
    email.getInfo();
  }
  void receive(Line line) {
    line.getInfo();
  }
  void receive(SMS sms) {
    sms.getInfo();
  }
  void receive(FBMessage fbMessage) {
    fbMessage.getInfo();
  }
}

寫程式是針對抽象、介面而寫,而不是針對具體類別而寫。

所以我們要做一個抽象類別或介面,裡面定義抽象方法,由實作介面的類別或繼承抽象類別的子類別,去實作抽象方法。

下圖中,介面IReceive有一個抽象方法getInfo(),實作此介面的類別(Email, Line, SMS, FBMessage)都要覆寫(Override)getInfo()的方法。

img

下圖中,Person類別的receive()方法使用到IReceive這個介面,作為方法參數。

img

程式碼如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
interface IReceive {
  void getInfo();
}

class Email implements IReceive{
  @Override
  public void getInfo() {
    System.out.println("email");
  }
}

class FBMessage implements IReceive{
  @Override
  public void getInfo() {
    System.out.println("FB Message");
  }
}

class Line implements IReceive{
  @Override
  public void getInfo() {
    System.out.println("Line");
  }
}

Person

1
2
3
4
5
class Person {
  void receive(IReceive receive) {
    receive.getInfo();
  }
}

main主程式

1
2
3
4
5
6
  public static void main(String[] args) {
    Person person = new Person();
    person.receive(new Email());
    person.receive(new Line());
    person.receive(new FBMessage());
  }
email
Line
FB Message

results matching ""

    No results matching ""