依存性逆転の原則をGolangを用いて解説(SOLID原則)

## 目次
- [背景](#背景)
- [依存性逆転の原則(DIP)とは](#依存性逆転の原則dipとは)
- [コードを用いた説明](#コードを用いた説明golangでのmodel-view-controllerのケース)
    - [従来の構成](#従来の構成)
    - [依存性逆転(DIP)構成](#依存性逆転dip構成)
- [まとめ](#まとめ)
- [参考URL](#参考url)

## 背景
インターフェースの意義を調べていく中でSOLID、依存性逆転の原則について理解する必要があったため、これらの調査内容をまとめる。

## 依存性逆転の原則(DIP)とは

[SOLID](https://ja.wikipedia.org/wiki/SOLID)(オブジェクト指向に用いられる原則)の頭文字
S 単一責任の原則 (single-responsibility principle)
O 開放閉鎖の原則（open/closed principle）
L リスコフの置換原則（Liskov substitution principle）
I インターフェース分離の原則 (interface segregation principle)
D <font color="red">依存性逆転の原則（dependency inversion principle）

5つ目のD依存性逆転の原則（dependency inversion principle）について

上位のモジュールのレイヤーが下位モジュールのレイヤーに依存させず、下位・上位モジュールともにそれぞれの抽象に依存すべきという考え方で、以下Wikiからの引用です。
>1.上位モジュールはいかなるものも下位モジュールから持ち込んではならない。双方とも抽象（例としてインターフェース）に依存するべきである。
"High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces)."[3]

>2.抽象は詳細に依存してはならない。詳細（具象的な実装内容）が抽象に依存するべきである。
"Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions."[3]

## コードを用いた説明(GolangでのModel View Controllerのケース)

### 従来の構成
- Wheat(小麦) 　　　　　ストラクト
- Udon(うどん)　　　　　”かけうどん”を作るメソッド
- konekone(麺をこねる)　Udonメソッドを呼び出すメソッド

    インターフェースを使わず、上記のメソッドやストラクトを使う従来の構成で"かけうどん"を作ります。

上位モジュール(konekone)が下位モジュール(Wheat)に依存している状態

```golang:Udon.go
package main

import (
        "fmt"
)

type Wheat struct {}

func (wh *Wheat) Udon() {
        fmt.Println("かけうどん")
}

// Wheat という具象に依存している
func konekone(wheat *Wheat) {
        wheat.Udon()
}

func main() {
        wheat := &Wheat{}
        konekone(wheat)
}
```
実行結果
```
$ go run Udon.go
かけうどん
```
```mermaid
%%{
  init: {
    'theme': 'base',
    'themeVariables': {
      'fontFamily': 'arial',
      'fontSize': '18px',
      'primaryTextColor': '#000',
      'secondaryColor': '#fff',
      'primaryBorderColor': '#000',
      'secondaryBorderColor': '#fff',
      'tertiaryColor': '#fff',
      'tertiaryBorderColor': '#000',
      'tertiaryTextColor': '#000',
      'noteBkgColor': '#fff',
      'noteTextColor': '#000',
      'noteBorderColor': '#000',
      'lineColor': '#F8B229',
      'textColor': '#000',
      'mainBkg': '#fff'
    }
  }
}%%

graph LR
  subgraph "下位モジュール"
    B-1(Wheat)
  end
  subgraph "上位モジュール"
    A-1(konekone)
  end
  A-1-->|依存|B-1

```


### 依存性逆転(DIP)構成
- Wheat(小麦) 　　　　　ストラクト
- Udon(うどん)　　　　　”かけうどん”を作るメソッド
- konekone(麺をこねる)　Udonメソッドを呼び出すメソッド
- <font color="red">**Shokunin(職人)**　</font>　　　追加されるインターフェース

    従来の構成にインターフェースShokuninを追加して依存関係を逆転させます。

下位モジュール(Wheat)が上位モジュール(Konekone)の抽象(インターフェースShokunin)に依存している状態
```golang:Udon-shokunin.go
package main

import (
        "fmt"
)

// Konekone() を持つインターフェースの定義
type Shokunin interface {
        Udon()
}

type Wheat struct {}

func (wh *Wheat) Udon() {
        fmt.Println("かけうどん")
}

// 引数として Shokunin インターフェースを定義
func konekone(shokunin Shokunin) {
        shokunin.Udon()
}

func main() {
        wheat := &Wheat{}
        konekone(wheat)
}
```
実行結果
```
$ go run Udon-shokunin.go
かけうどん
```
```mermaid
%%{
  init: {
    'theme': 'base',
    'themeVariables': {
      'fontFamily': 'arial',
      'fontSize': '18px',
      'primaryTextColor': '#000',
      'secondaryColor': '#fff',
      'primaryBorderColor': '#000',
      'secondaryBorderColor': '#fff',
      'tertiaryColor': '#fff',
      'tertiaryBorderColor': '#000',
      'tertiaryTextColor': '#000',
      'noteBkgColor': '#fff',
      'noteTextColor': '#000',
      'noteBorderColor': '#000',
      'lineColor': '#F8B229',
      'textColor': '#000',
      'mainBkg': '#fff'
    }
  }
}%%

graph LR
  subgraph "下位モジュール"
    B-1(Wheat)
  end
  subgraph "上位モジュール"
    A-1(konekone)
    C-1(<< interface >><br>Shokunin)
  end
  A-1-->|依存|C-1
  B-1-->|依存|C-1

```


実行結果はどちらも同じ"かけうどん"で、インターフェースを追加して依存が逆転していることがわかる！

## まとめ
従来の構成である麺をこねる作業が小麦に依存していた状態から、職人インターフェース(konekoneのインターフェースShokunin)を設置することで小麦は職人インターフェースに依存するよう、依存関係が逆転しました。
この構成によりメソッド間を疎結合でき、テストや変更がしやすい柔軟のコードを実装できるメリットがあります。
### 参考URL
https://ja.wikipedia.org/wiki/%E4%BE%9D%E5%AD%98%E6%80%A7%E9%80%86%E8%BB%A2%E3%81%AE%E5%8E%9F%E5%89%87

https://alpacat.com/posts/about-dependency-inversion