【Unity】Unityで学ぶデザインパターン06: Adapter パターン【デザパタ】

# はじめに
様々な言語で「デザインパターン」の本が世の中にありますが、筆者個人の経験では
`いまいちピンとこない例` `いまいちピンとこないコード` で説明されてることが多く、
`結局これっていつ使うの？` という疑問に答えるには仕事仲間等との議論をしないと
辿り着けないことが多々ありました。

そこで特に「ゲーム開発ではどう使うか？」にフォーカスを当てて、実践的な例を交えて
デザインパターンの説明の需要があると思い記事を作りました。

## デザインパターンを学ぶ理由

デザインパターンを学ぶ理由としては
1. 車輪の再発明の防止
1. 長文で読みにくいコード（可読性の低いコード）を減らす
1. コードを疎結合にして変更に強くなる(変更時のコスト・変更箇所を減らす)
1. モジュールとして使いまわせるように、コードの再利用性を高める
といった効果を期待できます。

## 対象読者
Unity 全くの初心者(インストールしただけで触ったことがないような方)はお断りです。
最低限以下のことは理解・経験を積んでおくことが必須になります。

- MonoBehaviour 継承クラスでコードを書いたことがある
- C# のピュアクラスを用いた自作クラスを作ったことがある
- クラスの継承という概念は知っている

そのため、`脱・初心者` `中級者へのステップアップ` として `デザインパターンを学ぶ` のが良いと思います。


# デザパタ記事リンク
## 生成系
1. [AbstractFactory パターン](https://qiita.com/Cova8bitdot/items/e863cecf48c0529ba05a)
1. [Builder パターン](https://qiita.com/Cova8bitdot/items/9dcdfeb0641bc774b1f8)
1. [FactoryMethod パターン](https://qiita.com/Cova8bitdot/items/61a38fd51735f321e564)
1. [Prototype パターン](https://qiita.com/Cova8bitdot/items/0bc251bc36201985c204)
1. [Singleton パターン](https://qiita.com/Cova8bitdot/items/29b7064c7472a6f34972)

## 構造系
1. [Adapter パターン](https://qiita.com/Cova8bitdot/items/f09776957073cf64902b)（本記事)
1. [Bridge パターン](https://qiita.com/Cova8bitdot/private/5b528216952c74436045)
1. [Composite パターン](https://qiita.com/Cova8bitdot/items/1c57d856027a33e99eb0)
1. [Decorator パターン](https://qiita.com/Cova8bitdot/items/e1373a756b3dfd86c920)
1. [Facade パターン](https://qiita.com/Cova8bitdot/items/bdf0976bdfa83e57f121)
1. [Flyweight パターン](https://qiita.com/Cova8bitdot/items/7f1f1f04b46ebaf43c5e)
1. [Proxy パターン](https://qiita.com/Cova8bitdot/items/8a27137812e103ec1ee3)

## 様態・ふるまい系
1. [Chain of Responsibility パターン](https://qiita.com/Cova8bitdot/items/66c62dd96adffda7e72e)
1. [Command パターン](https://qiita.com/Cova8bitdot/items/9a88f7fc0782c729f97c)
1. [Interpreter パターン](https://qiita.com/Cova8bitdot/items/a871c1de813d14049934)
1. [Iterator パターン](https://qiita.com/Cova8bitdot/items/302f19863cc3b2235625)
1. [Mediator パターン](https://qiita.com/Cova8bitdot/items/be33b97f35c84e814df7)
1. [Memento パターン](https://qiita.com/Cova8bitdot/items/ae7e6f5d2da7b07d379b)
1. [Observer パターン](https://qiita.com/Cova8bitdot/items/632782ad5264baf6a366)
1. [State パターン](https://qiita.com/Cova8bitdot/items/ab9fc16ac3a6657fdce0)
1. [Strategy パターン](https://qiita.com/Cova8bitdot/items/28dd773075cf6e9fefee)
1. [TemplateMethod パターン](https://qiita.com/Cova8bitdot/items/f0bed164ef6563b489d0)
1. [Visitor パターン](https://qiita.com/Cova8bitdot/items/15c56d40435adf63891d)


# Adapter　パターンについて
Adapterパターンとはあるクラスが特定のインターフェースを持っておらず、そのクラスを編集不可能な状態のときに特定インターフェースを使えるようにするデザインパターンの一つです。


# Adapter パターンの使い所

ゲーム開発においては「売り切り（買い切り）」のゲームではかなり効果が薄いデザインパターンです。
しかし、「運用系ゲーム」および「外部SDKを多用する開発現場」では特に威力を発揮するデザインパターンです。

## SDKの共存
ゲーム開発でSDK_Aを利用していたところ、別のSDK_Bも追加で使うなんていう場面があったりします。
スマホゲームならSNS連携などがまさにこの事例ですね。
TwitterAPI, Facebook, LINE, Instagram...　特にビジネス都合でアプリ側に連携を対応してほしいと急遽開発現場に飛び込んでくるのは炎上プロジェクトあるあるかと思います（2敗)。

このときSDK_AのAPIを利用するためにインターフェース経由でGameアプリ側が利用していましたが、SDK_Bには同じインターフェースは存在しないことがほとんどです。

```mermaid
classDiagram
  class GameApp
  GameApp --> GameSDKInterface: use

  class GameSDKInterface {
    <<interface>>
    +method(data)
  }

  class SDK_A {
    +method(data)
  }
  GameSDKInterface <|-- SDK_A


  class SDK_B{
    + someApi(data)
  }
  
```

そこで、このSDK_Bを改変せずにインターフェースを実装するのがAdapterパターンです。
具体的にはSDK_Bを内部に保持して目的のインターフェースを実装した新規クラスを用意する形です。

先ほどのクラス図に適応すると以下のようになります。

```mermaid
classDiagram
  class GameApp
  GameApp --> GameSDKInterface: use

  class GameSDKInterface {
    <<interface>>
    +method(data)
  }

  class SDK_A {
    +method(data)
  }
  GameSDKInterface <|-- SDK_A


  class SDK_B{
    + someApi(data)
  }
  class SDK_B_Adapter{
    +method(data)
    - sdk : SDK_B
  }
  GameSDKInterface <|-- SDK_B_Adapter
  SDK_B_Adapter o-- SDK_B

```

クラス `SDK_B_Adapter` がAdapterパターンそのものです。このように実装すればSDK_Bに手を加えることなく 開発者側で自由にコードを組むことができます。

## ゲームロジックの応用例

レアケースではありますが、例えば「スキルの転用」という意味では先ほどの例に近いものがあります。
たとえばPassiveSkillとActiveSkill でスキルが分かれてる時に、片方のスキルで実装したのをもう一方のスキルとして利用したい場合などでもAdapterパターンは有効です。

（まぁスキルをちゃんと抽象化しておきましょうという正論は置いておいて）

他にも「武器（装備）にスキルスロットが追加された」等、長年運用をしているゲームだとよくある新機能の要素で
既存機能の組み合わせで無理やり表現する時などに役に立ちます。

# まとめ
Adapterパターンは特にSDKの組み込みで威力を発揮するデザインパターンです。
インターフェース・SDK双方に手を加えることなく自然に繋げる効果としては非常に大事なデザインパターンなので
覚えておくと損はないでしょう。