37
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

Laravel - 『ドメイン駆動設計入門』してみて Clean な世界を垣間見た話し

Last updated at Posted at 2020-03-08

要約 / inb4 tl;dr

はじめに

前回の記事 でも書いたのですが、2020年2月9-11日に開催された PHPerKaigi2020 に参加してきました。

image.png
PHPerKaigi 2020

ここで以下の本を知り、DDDの面白さにのめり込み、ここ数日はずっと関連書籍を眺めております。

image.png
ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本 - Amazon

上図の書籍に記載したサンプルコードを Laravel で書き起こしてみて、なんとなく雰囲気は掴んだのですが、実践する場合のアーキテクチャ部分にモヤモヤが残っていました。

そこで、以下のコードなどを参考にしながら オレオレ・クリーン・アーキテクチャ Based on DDD を作ってみました。

主要な要素を 成瀬允宣さん(Twitter , nrslib )の記事やコードを参考とさせて頂きつつ、情報を再編成しながらまとめてみたというのが、この記事の概要です。

DDD で Clean な アーキテクチャ

そんなわけで、【 DDD × Clean Architecture × Laravel 】で良い感じの構成を考えてゆきます。

The Clean Architecture

クリーンアーキテクチャといえばこの図というのが以下(らしい)です。

image.png
引用:The Clean Architecture 13 August 2012 - Clean Coder Blog
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

この図は、上記の Uncle Bob こと Robert C. Martin 氏 のブログ記事や、書籍『Clean Architecture 達人に学ぶソフトウェアの構造と設計』で紹介されています。

また、同じ文脈で以下の図も クリーンアーキテクチャ を表現する図として知られています。

image.png

この2番目の図は、ネット記事では出どころが明記されているものがあまりなかったのですが、書籍『Clean Architecture 達人に学ぶソフトウェアの構造と設計』の中に、同心円図の後にこの図が紹介されてました。(注:<DS>1、<I>2

DDD & The Clean Architecture

全く関係の無さそうな上の2つの図ですが、成瀬さんの記事 を見ると、実は密接に関連していることが分かりました。
そこで、モノクロの2番目の図に、同心円で使われた色を使って分類すると下図のようになりました。

tenh-note-laravel-ddd (11).jpg

少しだけ分かりやすくなった気がします。
こういった Clean Architecture と DDD の関連については、以下の記事で詳細に説明されています。

次に、上記の記事で解説された内容をざっくりと表にまとめてみます。

『Clean な同心円図』 と 『DDD』

まずは 同心円図 と DDD。
image.png

# Clean DDD
1 Entities Domain Model
(Entity, Value Object, Domain Service)
2 Use Cases Application Service
3 Controllers -
4 Gateways Repository
5 Presenter -

『Clean な同心円図の右下』 と 『DDD』

同心円図の右下の図と DDD。

image.png

# Clean DDD
1 Controller -
2 Use Case
Input Port
Application Service
Interface
3 Use Case
Interactor
Application Service
4 Use Case
Output Port
???
5 Presenter ???

『データベースを使ったWebベースの~』 と 『DDD』

「Webベースのシナリオ~」の図 と DDD。

# Clean DDD Code
1 Controller - **Controller
2 Presenter - **Presenter
3 View Model <DS> - **ViewModel
4 View - blade
5 Input Data <DS> Command Object
(DTO)
**Request
6 Input Boundary <I>
Use Case Input Port
Application Service
Interface
**UseCaseInterface
7 Use Case Interactor Applicatoin Service **UseCaseInteractor
8 Output Boundary <I>
Use Case Output Port
- **PresenterInterface
9 Output Data <DS> - **Response
10 Data Access Interface <I> Repository Interface **RepositoryInterface
11 Data Access Repository **Repository
12 Database - (MySQL)
13 Entities Domain Model
(Entity, Value Object, Domain Service)
User
UserId
UserService
Specification

『データベースを使ったWebベースの~』に DDD な名前を当てはめる

前節までの情報を元に、DDDの概念を『データベースを使ったWebベースの~』図にあてはめると以下のようになりました。

img.jpg

おぉ。なんとなく、なんとなくそれっぽい。

ぼくのかんがえたさいきょうの

そんなこんなで 前回の記事 で実装したコードの構成を改変して以下のような オレオレ・クリーン・アーキテクチャ Based on DDD が出来上がりました。

img.jpg

ざっくりディレクトリ構成は以下の感じです。

Laravel_Directory_Structure
# OreOre Architecture based on DDD using Laravel
# 
# - Entities と UseCases と pacakes ディレクトリ配下に Domain/Context 単位に作成
#   - 以下の場合は Techno が namespace のトップ。
# - `Clean` な方の `Interface Adapter` は `Laravel/app` に配置。
# 
/
├── packages/
│  └── Techno                        # DDD: Domain
│      └── Sns                       # DDD: Context (Sub Domain ?)
│          ├── Entity                # Clean: Entities
│          │   ├── Core              # 抽象化オブジェクトなど
│          │   ├── Exceptions        # ドメイン特有の例外クラス
│          │   ├── Model
│          │   │   ├── Circle        # DDD: Entity, Value Object, Specification
│          │   │   └── User          # DDD: Entity, Value Object, Specification
│          │   └── Service           # DDD: Domain Service
│          └── UseCase               # Clean: Use Cases
│              ├── Application       # Clean: Use Case Interactor
│              │   ├── Circle        # DDD: Application Service
│              │   │   ├── Create    # ex.) CircleCreateUseCaseInteractor
│              │   │   ├── Invite
│              │   │   ├── Join
│              │   │   └── Update
│              │   └── User          # DDD: Application Service
│              │       ├── Delete    # ex.) UserDeleteUseCaseInteractor
│              │       ├── GetInfo
│              │       ├── Register
│              │       └── Update
│              └── Interface
│                  ├── Circle        # Clean: Input Data, Input Boundary, Output Boundary, Output Data
│                  │   ├── Create    # ex.) CircleCreateUseCaseInterface, CircleCreateRequest, CircleCreateResponse, CircleCreatePresenterInterface
│                  │   ├── Update
│                  │   ├── Invite
│                  │   ├── Join
│                  │   └── Gateway   # Clean: Gateways ( Data Access Interface)
│                  └── User          # Clean: Input Data, Input Boundary, Output Boundary, Output Data
│                      ├── Delete    # ex.) UserDeleteUseCaseInterface, UserDeleteRequest, UserDeleteResponse, UserDletePresenterInterface
│                      ├── Update
│                      ├── GetInfo
│                      ├── Register
│                      └── Gateway   # ex.) UserRepositoryInterface, UserFactoryInterface, UserNotificationInterface
│
├──app/
│  ├── Aspect
│  │   └── Modules
│  │       ├── LogExceptionsModule.php
│  │       ├── LoggableModule.php
│  │       └── TransactionalModule.php
│  ├── Console
│  ├── Database
│  │   └── Eloquent
│  ├── Exceptions
│  ├── Http
│  │   ├── Controllers               # Clean: Controllers
│  │   │   ├── Auth
│  │   │   ├── Controller.php
│  │   │   └── UserController.php
│  │   ├── Kernel.php
│  │   ├── Middleware
│  │   ├── Models
│  │   └── Presenter                 # Clean: Presenters
│  │── Providers
│  │   └── AppServiceProvider.php
│  └── Gateway                       # Clean: Gateways (Data Access)
│       ├── Notification             # ex.) UserNotification
│       ├── Eloquent
│       │   ├── Circle               # ex.) ELCircleRepository
│       │   └── User
│       ├── InMemory
│       │   ├── Circle               # ex.) IMCircleRepository
│       │   └── User                 # ex.) IMUserRepository
│       └── QueryBuilder
│           ├── Circle
│           └── User                 # ex.) QBUserRepository
├── bootstrap
├── composer.json
├── config
├── resources                        # Clean: View
├── routes
└── tests/
    ├── Feature
    │   └── Http
    │       └── Controllers
    └── Unit
        └── packages
            └── Techno

残課題

  • UseCase 内に配置した RepositoryInterface などなどの位置付けに悩み中です。

おわりに

まだ「絵に書いた持ち」状態なので、余裕があれば Code と共にアップデートします。

参考

以下の Web勉強会 を聞きながらこの記事を書いてましたが、これもまた大変勉強になりました。

image.png

書籍も購入しました!

image.png
ドメイン駆動設計 モデリング/実装ガイド - little-hands - BOOTH

あと書き

そもそもは 【 Kotlin + Spring Boot 】 が今後の潮流になると思い、お試し実装の前に アーキテクチャについて調べだして出会ったのが DDD 本でした。
最初から Kotlin で実装するより、ある程度慣れている Laravel で実装しようと思い色々と調べてみて、多くの参考になる情報に出会うことが出来ました。

ここまで調べてみて、 Clean Architecture 以外の実装パターンについても知りたい欲が強くなり、 Layered Architecture 、 Hexagonal Architecture 、 Onion Architecture などなど、自分なりに腹落ちする解釈を得たいと感じてますが、個別の解説記事はあれど、体系的に解説された情報に行き着いておりません。

いまの所、以下の記事が一番全体像を掴んでいるのでは、というところ。

DDD も 各種アーキテクチャも、時代ごとのバックボーンを背景に生まれ、適用されてきており、そういった情報も含めて全体像を掴んでみたいです。どこかに良いまとめはないものか。

欲しいものの整理

  • ★ フルスクラッチでシステム構築する時の参考となる Directory / File のサンプルとその解説情報
    • ◉『「軽量DDD」を突き詰める』感じになりそう。
    • ◉対象のシステム
      • Mobile ( iOS/Swift / Android/Kotlin )
      • Web Application
        • Web Client Application ( Web Frontend ) - Vue, React
        • Web Server Application ( Web Backend ) - PHP/Laravel, Kotlin/SpringBoot
      • mBaaS や FaaS 、IDaaS などとの付き合い方
      • 時代背景によってことなるはずなので、1970年以降で整理すると良いかも。
        • システムの用途
        • システムが与えた社会的影響
        • 主要技術
        • 主要デバイス
        • 主要インターフェース
        • 主要通信技術
        • 主要システム構成
        • 主要言語と言語の特徴
        • 主要プロトコル
        • 例えば
          • Main Frame
          • Personal Computer
          • Client-Server
          • World Wide Web
          • Web Application
          • Mobile Application
          • Cloud
    • ◉解説情報
      • MVC , MVP , MVVM などとの関係
      • 時代背景を元に、その概念やデバイスが生まれた経緯や適用された方法など
      • 情報の原典となる書籍や記事
        • 書籍:エリック・エヴァンスのドメイン駆動設計 (原作和訳
        • 書籍:実践ドメイン駆動設計 (原作和訳
        • 書籍:ユースケース駆動開発実践ガイド (原作和訳
        • 書籍:モデルベース要件定義テクニック (書籍
        • 書籍:Clean Architecture 達人に学ぶソフトウェアの構造と設計 (原作和訳
        • WebSite:ヘキサゴナルアーキテクチャ - blog.tai2.net (原作 - サイト工事中、和訳
        • WebSite:Clean Architecture - Clean Coder Blog - Uncle Bob (原作和訳
        • WebSite:DDD Resources - Domain Language
      • 情報の濃度と段階
        • よく言われるやつ
          • 実体験
          • メディア
            • 新聞
            • 雑誌
            • 書籍
            • Web
            • 動画
            • TV
            • 研究論文
        • 整理したい対象
          • 原典
          • 解説書籍
          • 解説の解説書籍
          • 実装例
          • 調べてみた系
        • 生データに近いものを見つけて整理する
  • 実践的DDD
  1. <DS> : Data Structure

  2. <I> : Interface

37
34
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
37
34

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?