Slide 1

Slide 1 text

レイヤードアーキテクチャ (とDDD) テックフェス2023春 松浪 亮

Slide 2

Slide 2 text

Profile 松浪 亮(まつなみ りょう) Matsunami Ryo 出⾝:⼤阪府 ⼊社:2022/01 所属:レバテックID開発チーム 最近のお気に⼊り

Slide 3

Slide 3 text

今回お話しする内容は... レイヤードアーキテクチャ

Slide 4

Slide 4 text

10か⽉くらい前にも話してたけど... ※ アーキテクチャスキルアッププロジェクト

Slide 5

Slide 5 text

発表して半年経ってから いちゃもん コメントが...

Slide 6

Slide 6 text

要約すると、
 「内容薄いからもっと詳しく書け」 
 発表して半年経ってから いちゃもん コメントが...

Slide 7

Slide 7 text

レイヤードアーキテクチャ(改) (とDDD) テックフェス2023春 松浪 亮

Slide 8

Slide 8 text

今回お話しする内容は... [1] レイヤードアーキテクチャについて、おさらい

Slide 9

Slide 9 text

今回お話しする内容は... [1] レイヤードアーキテクチャについて、おさらい [2] コードを元にレイヤードアーキテクチャを解説

Slide 10

Slide 10 text

今回お話しする内容は... [1] レイヤードアーキテクチャについて、おさらい [2] コードを元にレイヤードアーキテクチャを解説 [3] DI(依存性の注⼊)でコードをドメイン中⼼に作り変える

Slide 11

Slide 11 text

⽬次 1. レイヤードアーキテクチャについて 2. コードでレイヤードアーキテクチャを理解する 3. DIでドメイン中⼼に作り変える 4. まとめ

Slide 12

Slide 12 text

⽬次 1. レイヤードアーキテクチャについて 2. コードでレイヤードアーキテクチャを理解する 3. DIでドメイン中⼼に作り変える 4. まとめ

Slide 13

Slide 13 text

レイヤードアーキテクチャ エリック・エヴァンスのドメイン駆動設計(翔泳社)

Slide 14

Slide 14 text

4つのレイヤーに分けてモジュールを配置 ■Infrastructure層 データストアへの永続化や外部APIとの通信など技術 的な機能を実装する ■Domain層 ドメイン(ソフトウェアで解決したい対象領域のこ と)モデルのルール/制約を実装する ■Application層 ドメイン層を組み合わせてユースケースを実装する ■Presentation層 UIやユニットテストなど、アプリケーション(ユース ケース)層を呼び出すコードを実装する

Slide 15

Slide 15 text

ルールは1つだけ エリック・エヴァンスのドメイン駆動設計(翔泳社) 依存OK 依存NG

Slide 16

Slide 16 text

依存関係について 依存する側 依存される側 依存⽅向

Slide 17

Slide 17 text

依存関係について 依存する側 依存される側 依存⽅向 変更 依存関係について

Slide 18

Slide 18 text

依存関係について 依存する側 依存される側 依存⽅向 変更 影響あり 依存関係について

Slide 19

Slide 19 text

依存関係について 依存する側 依存される側 依存⽅向 変更 影響あり 変更 依存関係について

Slide 20

Slide 20 text

依存関係について 依存する側 依存される側 依存⽅向 変更 影響あり 変更 影響なし 依存関係について

Slide 21

Slide 21 text

依存関係について 依存する側は影響を与えないので改修・変更が容易になり、 依存される側は変更の影響を受けないので依存する側よりも安定する。 依存関係について 依存する側 依存される側 依存⽅向 変更 影響あり 変更 影響なし

Slide 22

Slide 22 text

依存関係について 変更頻度が⾼い機能は依存する側(上位の層)に、 変更の影響を受けたくない機能は依存される側(下位の層)に設計すべき。 依存する側は影響を与えないので改修・変更が容易になり、 依存される側は変更の影響を受けないので依存する側よりも安定する。 依存関係について 依存する側 依存される側 依存⽅向 変更 影響あり 変更 影響なし

Slide 23

Slide 23 text

レイヤードアーキテクチャの問題点 エリック・エヴァンスのドメイン駆動設計(翔泳社) DomainがInfrastructureに依存してよいことになっている → 変更の影響を受けたくないはずのDomainが依存する側にある

Slide 24

Slide 24 text

レイヤードアーキテクチャの問題点2 エリック・エヴァンスのドメイン駆動設計(翔泳社) 理論上はPresentationもInfrastructureに依存してよい → Presentationからデータを更新できてしまう

Slide 25

Slide 25 text

ドメインルールがDomain層から漏れ出てしまう エリック・エヴァンスのドメイン駆動設計(翔泳社) 理論上はPresentationもInfrastructureに依存してよい → Presentationからデータを更新できてしまう → 本来、Domainにあるべき実装を   Presentationに実装できてしまう ドメイン ロジック

Slide 26

Slide 26 text

全体を⾒ないと仕様を把握できなくなる エリック・エヴァンスのドメイン駆動設計(翔泳社) 理論上はPresentationもInfrastructureに依存してよい → Presentationからデータを更新できてしまう → 本来、Domainにあるべき実装を   Presentationに実装できてしまう → 修正箇所が分散する → 達成したいことは全体を⾒ないとわからない ドメイン ロジック ドメイン ロジック

Slide 27

Slide 27 text

解決策 エリック・エヴァンスのドメイン駆動設計(翔泳社) Infrastructureからの依存の向きを変える → 依存性を逆転させる

Slide 28

Slide 28 text

つまり... ドメイン駆動設計 モデリング/実装ガイド(松岡 幸一郎さん:著) ドメインを中⼼に置く → ドメイン駆動設計

Slide 29

Slide 29 text

つまり... ドメイン駆動設計 モデリング/実装ガイド(松岡 幸一郎さん:著) 詳しくは...

Slide 30

Slide 30 text

⽬次 1. レイヤードアーキテクチャについて 2. コードでレイヤードアーキテクチャを理解する 3. DIでドメイン中⼼に作り変える 4. まとめ

Slide 31

Slide 31 text

例(コードサンプル) ● ユーザ情報を登録する超シンプルなWebアプリケーションを想定 ○ ⼊⼒として、name(⽒名)とemail(メールアドレス)を受け取る ○ バリデーションチェックを実施する ○ バリデーションに問題なければRDBに登録する ● レイヤードアーキテクチャに則って実装してみる ○ Presentation層 ■ → Application層 ● → Domain層 ○ → Infrastructure層

Slide 32

Slide 32 text

Presentation層

Slide 33

Slide 33 text

Presentation層 Presentation層

Slide 34

Slide 34 text

Presentation層 Presentation層

Slide 35

Slide 35 text

Application層

Slide 36

Slide 36 text

Application層

Slide 37

Slide 37 text

Application層

Slide 38

Slide 38 text

Domain層

Slide 39

Slide 39 text

Domain層 新規ユーザを⽣成時のドメイン知識(ルール/制約)を実装 →バリデーションチェックや初期設定など →常に正しいインスタンスしか存在させなくする

Slide 40

Slide 40 text

Infrastructure層

Slide 41

Slide 41 text

結果... EndPoint("/users/create") UseCase Entity Repository

Slide 42

Slide 42 text

⽬次 1. レイヤードアーキテクチャについて 2. コードでレイヤードアーキテクチャを理解する 3. DIでドメイン中⼼に作り変える 4. まとめ

Slide 43

Slide 43 text

ドメインを中⼼にするには... EndPoint("/users/create") 
 UseCase
 Entity
 Repository
 ← Repositoryを...

Slide 44

Slide 44 text

EndPoint("/users/create") 
 UseCase
 Repository
 Repository
 Entity
 ↑ DI(依存性の注⼊)する こうする...!!

Slide 45

Slide 45 text

こうする...?? EndPoint("/users/create") 
 UseCase
 Repository
 Repository
 Entity
 ↑ DI(依存性の注⼊)する

Slide 46

Slide 46 text

DI(依存性の注⼊)とは 依存性の注⼊(いぞんせいのちゅうにゅう、英: Dependency injection)とは、あるオブジェ クトや関数が、依存する他のオブジェクトや関数を受け取るデザインパターンである。 DIは制御の反転の⼀種で、オブジェクトの作成と利⽤について関⼼の分離を⾏い、疎結合な プログラムを実現することを⽬的としている。 by Wikipedia

Slide 47

Slide 47 text

DI(依存性の注⼊)とは?? 依存性の注⼊(いぞんせいのちゅうにゅう、英: Dependency injection)とは、あるオブジェ クトや関数が、依存する他のオブジェクトや関数を受け取るデザインパターンである。 DIは制御の反転の⼀種で、オブジェクトの作成と利⽤について関⼼の分離を⾏い、疎結合な プログラムを実現することを⽬的としている。 by Wikipedia

Slide 48

Slide 48 text

Presentation層

Slide 49

Slide 49 text

Presentation層

Slide 50

Slide 50 text

Presentation層

Slide 51

Slide 51 text

Application層

Slide 52

Slide 52 text

ドメインを中⼼にするために... ・Repositoryのインタフェースを⽤意する ・Infrastructureの実態をコンストラクタで渡す

Slide 53

Slide 53 text

ドメインを中⼼にするために... ・Repositoryのインタフェースを⽤意する ・Infrastructureの実態をコンストラクタで渡す  → DI(依存性の注⼊)

Slide 54

Slide 54 text

Application層

Slide 55

Slide 55 text

Application層 Applicationからインタフェースを参照(依存)する形に なった → Repositoryのコードの詳細が⾒えなくなった  → Infrastructureの実装に依存しなくなった!

Slide 56

Slide 56 text

Q.依存しなくなると何が嬉しいのか?

Slide 57

Slide 57 text

Q.依存しなくなると何が嬉しいのか? A.ユニットテストしやすくなる Q.依存しなくなると何が嬉しいのか?

Slide 58

Slide 58 text

ユニットテストでモックに差し替える ①インタフェースを実装したMockを⽤意する  → 適当な値を返す ③RDBに接続しないでユニットテストができる ②コンストラクタでMockを渡す

Slide 59

Slide 59 text

例外のパターンもテストしやすい ①インタフェースを実装したMockを⽤意する  → 例外を返す ③例外のパターンもユニットテストができる ②コンストラクタでMockを渡す

Slide 60

Slide 60 text

⽬次 1. レイヤードアーキテクチャについて 2. コードでレイヤードアーキテクチャを理解する 3. DIでドメイン中⼼に作り変える 4. まとめ

Slide 61

Slide 61 text

まとめ ● レイヤードアーキテクチャは下記の概念に沿って設計する ○ 4つのレイヤーで責務を分割する ○ 常に上位から下位の⽅向に依存させる ● ⽋点としてInfrastructure層に依存する設計となる ○ 依存関係を逆転させるためにDI(依存性の注⼊)を利⽤する ○ DIによってドメインを中⼼とした設計にすることができる ■ オニオンアーキテクチャが実現できる ● Infrastructure層に依存させないことでテストしやすくなる ○ Infrastructure層のコードの実態をMockに差し替えやすい

Slide 62

Slide 62 text

ご清聴ありがとうございました