今回の講習会での各アーキテクチャの説明は 以下の書籍・Webサイトをベースにしています (詳細情報は参考文献に書いています)
アプリケーションを層で分割するアーキテクチャ
層で分割されているので、ユニットテストが書きやすい。
DDDはLayered Architectureの中のDomain層を中心にして行うアプリケーションの設計。 物凄く簡単にいうと、「仕様に従うコードを書ける設計をするべき」ということ。
Domain層がInfrastructure層に依存
つまり、愚直に実装するとDDD的に良くない!
Domain層とInfrastructure層の依存関係を逆にすれば解決する
間にinterfaceを挟むことで、 依存の向きを逆にできる
interfaceの定義時には依存される側(今回ならDomain)の データしか使ってはいけない DBのテーブル構造関係のデータとかはNG
interfaceにclass(Goならstruct)を割り当てるコードを自動生成するツール。
JavaのSpring Bootのやつが有名。 Goの場合、wireを使うことが多い。
DIでLayered ArchitectureのDomain層とInfrastructure層の依存を逆転させる
Domainには3種類存在する
シンプルなチャットアプリ。 ユーザーがメッセージを投稿できる。
ものに紐づかない操作。
ex) メッセージの投稿。
概念として識別が可能なドメイン。
ex) User,Message @mazreanと@tokiは別のユーザー。
概念として識別ができないドメイン。 不変。
ex) ユーザー名 mazreanという文字列のユーザー名と、 tokiという文字列のユーザー名はそれ自体で識別することはない。 ユーザーになって初めて識別ができるものになる。
時間: 7min traP CollectionのサーバーサイドはDDDベースのアーキテクチャになっている。ドメインを見てみよう! https://github.com/traPtitech/trap-collection-server
DDDに対称性という考えを加えたもの Port, Adapterという見方が特徴
Hexagonal Architectureという名前の由来
異なる接続口を持つ外部アプリケーションを アプリケーションの用意したPortに合うように Adapterで変換してPortに繋ぐ
USB Type-Aのマウス(外部アプリケーション)を USB Type-C(Port)へ変換アダプタ(Adapter)で変換して PC(アプリケーション)に接続するイメージ
時間: 7min traP CollectionのサーバーサイドにもPort, Adapterの構造が存在する repository(データ永続化)のPort, Adapterを見てみよう! https://github.com/traPtitech/trap-collection-server
go generate
Hexagonal ArchitectureやOnion Architectureなどを統合して、 より実用的にしようとしたもの
Domainが消えていないHexagonal Architecture
DDDのメリット+Hexagonal Architectureのメリット
設計時によく現れる構造のパターン。 オブジェクト指向のパターンについて述べたGoFのものが有名。
以下のものを例として説明する
オブジェクトの生成と使用を分離するためのパターン。 依存関係の逆転を実現するもう1つの方法。 ただし、DI Containerがあれば基本DIの方が楽。
欲しいinterfaceに合わないライブラリなどのinterfaceを、 欲しいinterfaceに合わせるデザインパターン
class、interfaceの名前に注目。 Hexagonal ArchitectureのPort・Adapterの考えは、 Adapter Pattern由来であることがわかる。
デザインパターンを使うと通常構造が複雑になる
デザインパターンは問題解決の手段。
誤: 使えるから使う 正: 〜という問題を解決できるから使う
デザインパターンは問題を明確にした上で使うべき。
多くのアプリケーションで発生する問題が存在する。 ex) 外部サービスのアップデートに追従しやすくしたい
これに対処できるようなデザインパターンなどの組み合わせがアーキテクチャ
最終的な目的は「開発の円滑化」 そのために、アプリケーションに適した
などを実現するのが目的
柔軟さを生み出す手段としてAdapter Patternを使う場合
欲しい項目全てを実現することはできない!
トレードオフのバランスを見て、 アプリケーションに適した
などのバランスを実現すること
などのバランスを実現するのが目的 →適切なバランスについて考えるべき
自分の場合、以下のような流れで行なっている
を予定していた。 逆に仕様は長年話していてそれなりに固まっていた。 Clean Architectureをベースにした。
各層の中で細かく共通化したい部分が発生しそうだったので、 そのような部分を構造体で切り出して委譲するようにした。
自分は以下のステップが良いと考えている
Q. interfaceはどのぐらい抽象化すべき? A. 想定される変更に対するコストが最小になる程度
Q. Clean Architectureするとコード量が増えて辛い A. 規模に対してClean Architectureではオーバースペックな可能性大
アーキテクチャを使う際には
という流れを踏むと良い
長いものでなくて良いので、講習会をやってみてください!
など、良いことが無限にあります。