【ミライトデザイン社内勉強会#3】デザインパターン


# デザインパターンとは

- 一言で言うと、設計のノウハウ集

[デザインパターン (ソフトウェア) - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3_(%E3%82%BD%E3%83%95%E3%83%88%E3%82%A6%E3%82%A7%E3%82%A2))

- パターンにあう状況、必要な時だけ使えばいい。

### 有名なデザーンパターン
- 「オブジェクト指向における再利用のためのデザインパターン」(通称「GoF本」)
    - Erich Gamma,Richard Helm,Ralph Johnson,John Vlissides の四人を合わせて the Gang of Four
    - 23個

### デザインパターンのメリット

- 再利用性の高い柔軟な設計ができる
    - いろんな人のノウハウ、経験が詰まっているのでクオリテーが高い
    - 設計者の経験や直感などに依存していたのをパターン化することによって、他の人もそのパターンを再利用できる
- パターンに名前がついていることによって、技術者どうしの意思疎通が容易になる
    - パターンの名前でコミュニケーションが取りやすくなる
    
## Iteratorパターン

[1. Iteratorパターン 1 | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Iterator/Iterator1.html/)

- いまや、恩恵はみんな預かっている。
- 自分らで設計することがほとんどない。
    - 言語の機能として組み込まれているので、自分で実装することはあまりない。
    - フレームワークやら言語やらのほうで既に実装済みなことが多い。

- 走査方法って？
    - データの集合をどうゆう基準で1つづつ見ていくか。
        - 大きい順なのか、入れた順番なのか、年齢順なのかとか。

- **データが入っている集合と、操作方法を分けたパターン**
    - 配列オブジェクトと取得方法オブジェクトを分ける。みたいな感じ。

## Adapterパターン
[2．Adapter パターン 1 | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Adapter/Adapter1.html/)


- **Adapterパターンは、インターフェースに互換性のないクラス同士を組み合わせることを目的としたパターン**
- adapt: 「適合させる」
- adapter: 「適合させるもの」
- 継承を利用したパターンと、委譲を利用したパターンがある。

### 継承を利用したパターン

- extends
- アダプタークラスをそのものを継承するか

### 移譲を利用したパターン

- DI
- アダプタークラスをコンストラクタで渡して使うか

## TemplateMethodパターン

[3．TemplateMethod パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/TemplateMethod.html/)

- abstractメソッドの使い方を説明しているだけな気がする。
- abstractクラスが何かがわかれば理解できる。
    - インターフェースとの違いは？
        - abstractクラスは実装を書くことができる。
- アンンチパターンな気がする。
    - 継承が前提になっているので、依存関係になる。
    - 抽象メソッドではないメソッドを子クラスごとに書き換え始めると、アンチパターンになりやすい。
- フレームワークの内部ではよく使われている。
    - 実装するよりも利用することが多いかも。
- DIでインターフェースを使うこともできる

## FactoryMethod パターン

[4\. FactoryMethod パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/FactoryMethod.html/)

- 例題だとDIで解決できる。
    - あんまり例題のような使い方はしないかも。
- 生成を手続きと分離して、生成に特化したクラスを作りたい。
- ただnewするだけじゃなくて、生成が複雑な時に生成の手続きをメソッドに分離する。
- 処理と生成を分ける。
- 複雑な生成ってなに？
    - 10個くらいのテーブルからデータを持ってきてインスタンスを生成するとか
    - 実際にはただnewすればいい方が少ないかも
    - DBアクセスが多い時など
- FactoryMethod パターンがいいたのは生成と実装を分けると言うこと。
- なんで生成と実装を分けるの？
    - 生成と実装が一緒だと、生成したもの専用のクラスになってしまう。
    - プログラミングは具象に対してではなく抽象したいして、処理を書いた方がいい。
    - 具象ではなく抽象に依存しろ
    
    ```
    hiro()
    {
        飲み物を飲む()
        {
            コーラを作る処理();
            
            飲む処理...
        }
    }
    // 生成と実装が分離されていないと
    // hiroさんはコーラしか飲めない
    
    hiro()
    {
         飲み物を飲む(飲み物クラス　飲み物)
        {   
            飲む処理...
        }
    }
    
    // hiroさんはコーラもタピオカも飲める。
    ```

## Singleton パターン

[5\. Singleton パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/Singleton.html/)

- クラスのインスタンスが一つしかないことを保証したい場合に使用する
- コンストラクタを private とすることで、他クラスから新たにインスタンスが生成されないような構造とすることで、インスタンスの生成を制御する
    - getInstanceメソッドを利用してインスタンスを使用する

## Strategy パターン

[10. Strategy パターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Strategy.html/)

- どんな時に使われるのか
    - if文がどんどん増えるような時
    - 同じインターフェースなので引数は同じじゃないとダメ
- メソッドに切り分けるだけじゃダメなの？
    - 2,3このif文なら問題ないかも
    - OCPに違反する
    - Strategyなら新しくクラスを追加すればいい
- アルゴリズムの差し替えをするのがStrategyパターン
- hiroさんはStrategyパターン + FactoryMethod パターンが好き
- 意思決定はクライアントコードで行う
- DDDではStrategyパターンのことをポリシーってよんでいる
    - [[ 技術講座 ] Domain-Driven Designのエッセンス 第3回｜オブジェクトの広場](https://www.ogis-ri.co.jp/otc/hiroba/technical/DDDEssence/chap3.html)
    > ● Responsibility Layers（責務の階層）パターン
オブジェクト指向設計では、各オブジェクトを責務の割り当てに基づいて設計する責務駆動設計（Responsibility Driven Design, RDD） が基本だが、RDDは大規模な構造に対しても適用可能だ。大規模な構造においては、アーキテクチャパターンのLayersパターンを責務の構造にも適用し、システム全体にまたがった「責務の階層構造」を考える。階層構造では、上位層は下位層に依存するが、下位層は上位層からは独立している。責務の階層は、システムの高次元の目的や設計を物語り、ドメインモデル設計のガイドラインとなる。責務の階層の一例を示すと、以下のようなものになる。

    > 意思決定（decision）層 … どんな戦略やポリシーを実行すべきかを決定する層
ポリシー（policy）層 … 戦略上のゴールや業務ルールを実際に適用する層
運用（operation）層 … 日常行なわれている業務を表す層
業務基盤（capability）層 … どんなリソースがあり、業務上なにが可能なのかを表す層

- クラスが多くなると逆に見づらくならない？
    - パッケージ構成ができていれば問題ない。
        - 1つ1つのディレクトリは10~20くらいにしかならないはず。
    - 1クラス1ファイルじゃない言語なら変わって来るかも。
        - jsとか
- 如何に抽象化できるかが大事。
    - 組み替え可能にする
    - 実装に依存するな抽象に依存しろ
        - 抽象に依存すれば処理の差し替えも簡単にできる

## Compositeパターン

https://www.techscore.com/tech/DesignPattern/Composite.html/


- 英語でcompositeは「複合物」
- OpenCrosedの原則を満たしてる
- ツリー構造になっているもので使える
- 削除意外には？
    - addとか、共通の操作をする時にインターフェースに切り出す
- インターフェースを積んでる時は基本インターフェースにあるメソッドだけが公開されていた方がいい
- インターフェース以外のパブリックメソッドを公開したらよくない
    - 使う側はインターフェース以外にクラスの内部構造まで知る必要が出てくるので、インターフェースのメリットがなくなってしまう。
    - プライベートメソッドがある分には問題ない
- 継承よりコンポジションを選ぶ（Effective Java）

## Decoratorパターン

https://www.techscore.com/tech/DesignPattern/Decorator.html/

- 英語で「装飾者」を意味する言葉
- Compositeパターンとほとんど同じ
- デザインパターンはインターフェースの活用方法のパターン
- Decoratorパターンは[ファクトリーパターン](https://esa-pages.io/p/sharing/14942/posts/118/84b994cf98d6d9d9c169.html)と組み合わせることがある
- アイスのトッピングもクラスやインターフェースになっていた方が汎用性が高いと思う


## Chain of Responsibilityパターン

[14．Chain of Responsibility パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/ChainOfResponsibility.html/)

- chain は「鎖」、responsibility は「責任」を意味します。したがって、 Chain of Responsibility は、「責任の鎖」と訳すことができます。
- Composite パターン、Decorator パターンと一緒
- チェインじゃなくてもループでもできる
    -  インターフェースでresponsibilityを作って、responsibilityを実装しているクラスをループで回して、判断できるクラスがあれば、結果が返ってくる。みたいな。
    -  判断と処理を分けるっていう考え方はチェインもループの場合も同じ
- 柔軟性はあるけど、読みにくいかも
    - ```nakagawa.setNext(rookie).setNext(veteran).setNext(staffMeeting);```
        - nakagawaくんクラスに先生クラスをsetNextしているところとか

## Facadeパターン

[15．Facadeパターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Facade.html/)

- カプセル化みたいなもの

- [ファサード 7.x Laravel](https://readouble.com/laravel/7.x/ja/facades.html)
    - Laravelだとファサードって呼ばれてるコンポーネントがある
    - どこからでも呼び出せるってことでつけてる
        - Laravelのファサードは本来の意味とは若干違うかも
        - ファサードはどこからでも使えるものという訳ではない。

- [java — ファサードとアダプターパターンの違いは何ですか？](https://www.it-swarm.dev/ja/java/%e3%83%95%e3%82%a1%e3%82%b5%e3%83%bc%e3%83%89%e3%81%a8%e3%82%a2%e3%83%80%e3%83%97%e3%82%bf%e3%83%bc%e3%83%91%e3%82%bf%e3%83%bc%e3%83%b3%e3%81%ae%e9%81%95%e3%81%84%e3%81%af%e4%bd%95%e3%81%a7%e3%81%99%e3%81%8b%ef%bc%9f/969647379/)
    - ファサードは手続きの隠蔽
    - アダプターはインターフェースの変換
        - ホントはtypeCしかつながらないのにアダプターを噛ませたらライトニングも使える、みたいなイメージ
- ファサードは処理を代行してくれてる
- ファクトリーパターンとは何が違うの？
    - ファクトリーは生成したインスタンスを返してくれる
    - ファサードは処理の窓口
        - インスタンスを返したらダメなの？
            - インスタンスを返してもいいけど、一般的には返さない。
            - 何を返すかは重要じゃない。

- DDDのアプリケーションサービスはファサードじゃないの？
    - 広義ではファサードと読んでもいいかも
        - 業務に対するファサードと言えるかも（アプリケーションサービスをファサードと実際に呼ぶことはないけど）

## Observerパターン

[17．Observer パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/Observer.html/)


- フロントエンドではよく使うけど、サーバーサイドではあんまり使わないかも
- 変更側から通知してくれるのがObserver
- インターフェースの有無は特に重要じゃない気がする
     - Observerパターンとしては必要かも
     - インターフェースがなくても実現できるんじゃない？
         - 型かインターフェースでupdate()メソッドを持ってる保証が必要
         - インターフェースじゃなくてもメソッドを持ってる保証があれば実現できそう
         - jsでもObserverパターンは聞くのでインターフェースはなくてもできそう
             - デザインパターンとしてはインターフェース前提なんじゃない？
             - デザインパターンはインターフェースを前提としていそう

- [Laravel の Listener, Subscriber, Observer それぞれの使い分けについてざっくり - Qiita](https://qiita.com/nunulk/items/0bd834f5ce5ff2479cae)
    - LaravelのObserverとObserverパターンはちょっと違う
    - Observerパターンは別にモデルのイベント意外を取得してもいい


## Stateパターン

[19．State パターン \| TECHSCORE\(テックスコア\)](https://www.techscore.com/tech/DesignPattern/State.html/)

- Strategy パターンとほとんど同じ
    - [10. Strategy パターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Strategy.html/)
    - Strategy パターンは状態を持たない
- Strategy パターンが状態を持ったもの

- privateなのは誤植っぽい？

```
   private void changeState(State state) {
        this.state = state;
    }
```

## Proxyパターン

[21．Proxyパターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Proxy.html/)

- インフラのプロキシと同じ意味
- キャッシュぽい
    - 自分が思ってないキャッシュは本体に聞くみたいな
- いつ使うの？
    - 思いつきにくい
    - アプリケーション側でキャッシュを実装したい時とか
    - 中間層を設ける時
        - 本体にあんまり負荷をかけたくない時
    - プロキシを経由して処理を分散したい時とか
    - [デザインパターン-Proxy CapmNetwork](http://capm-network.com/?tag=%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3-Proxy)
- Adapter、Facade と似てる
    - [c# — プロキシ、ラッパー、またはファサードクラスの違いは何ですか](https://www.it-swarm.dev/ja/c%23/%E3%83%97%E3%83%AD%E3%82%AD%E3%82%B7%E3%80%81%E3%83%A9%E3%83%83%E3%83%91%E3%83%BC%E3%80%81%E3%81%BE%E3%81%9F%E3%81%AF%E3%83%95%E3%82%A1%E3%82%B5%E3%83%BC%E3%83%89%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AE%E9%81%95%E3%81%84%E3%81%AF%E4%BD%95%E3%81%A7%E3%81%99%E3%81%8B/1069507203/)
        - やってることは同じ

## Commandパターン 

[22．Commandパターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/Command.html/)

- 対象を操作を分けている
- アップリケーション層がドメイン層を操作するのと広い意味で言えばやっていることは同じ
- コマンドの複雑な手続きをCommandオブジェクトに内包している
- ユーザーを操作するコマンドオブジェクトがあって、アップリケーションサービスで使用するみたいな
- OCP

# 参考
[デザインパターン | TECHSCORE(テックスコア)](https://www.techscore.com/tech/DesignPattern/index.html/)