LoginSignup
2
3

More than 1 year has passed since last update.

「ドメイン駆動設計入門」のLaravelによる実装例:Chapter 4-不自然さを解決する「ドメインサービス」

Last updated at Posted at 2023-06-11

本プロジェクトでは、成瀬允宣氏著の「ドメイン駆動設計入門」のLaravel 10を用いた実装例を示します。

当該書籍では、ドメイン駆動設計(Domain Driven Deplopment, DDD)を用いたWEBアプリケーションの開発例が示されており、素晴らしい著作であることは言うまでもありません。
しかしながら実装はC#で示されているため
、例えばPHPフレームワークの代表例であるLaravelなどでDDDによる実装を行いたい場合には、具体的な実装例が分かりづらくなってしまいます。

そこで本プロジェクトでは、「ドメイン駆動設計入門」のLaravelによる実装例を示すことで、Laravel開発者のDDD実装の手助けとなることを目指します。あくまでLaravelの実装例を示すことを目的としていますので、ドメイン駆動設計とは何かについては書籍をお読みください。

これが皆様の開発の手助けとなれば幸いです。ご意見等ございましたら、コメント欄やIssueでお伝えいただければと思います。

目次

Githubにソースコードはアップ済みです。

Chapter 4: 不自然さを解決する「ドメインサービス」

Docker環境で開発

あらかじめ、srcフォルダをVisual Studio Codeで開き、Command PaletteのDev Containers: Reopen in ContainerでDocker環境に入っておきます。

ドメインサービスとは

書籍では、ドメインサービスについて以下のように記述されています。

システムには値オブジェクトやエンティティに記述すると不自然になってしまう振る舞いが存在します。
ドメインサービスはそういった不自然さを解決するオブジェクトです。

具体的には、User用のドメインサービスとして、Userオブジェクトがすでに確認するかのメソッドを定義しています。
その他にも、書籍 Chapter4.5では、物流サービスの「輸送」の例を挙げています。
確かに「輸送」は倉庫や届け物が担う役割ではないため、新たにドメインサービスを作成するのが適していそうです。

Laravelでドメインサービスは必要か?

では、Laravelでドメインサービスを作成する場合はどうでしょうか?
私は、書籍で紹介されている、同じ名前のUserオブジェクトがすでに存在するかを確認するexistsメソッドなどをドメインサービスとして実装することは不要であると考えます。
なぜなら、LaravelのEloquentで既にこれらのメソッドが実装されているからです。

例えば以下のようにexistsメソッドを使用することができます。
適宜php artisan migrate:freshでデータベースをリセットして、実行結果を確認してみてください。

routes/web.php
<?php

use Illuminate\Support\Facades\Route;
use App\ValueObjects\UserName;
use App\Models\User;

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider and all of them will
| be assigned to the "web" middleware group. Make something great!
|
*/

Route::get('/', function () {
    $username = new UserName("ReiRev");
    $user = User::create(
        [
            "username" => $username
        ]
    );
    dd(User::where("username", $username)->exists());
    return view('welcome');
});

Eloquentでは、データベースやそれに付随する操作は全てEloquentモデル(エンティティ)にセットになっているため、追加でexistsのようなメソッドを実装するのは二度手間です。
ドメインサービスが不要というよりも、Eloquentの設計方針と合わせて考えると、あえて実装する必要はないと思います。

一方で、前節の「輸送」のようなドメインサービスはEloquentでは当然カバーできませんので、適宜実装する必要があるでしょう。
例えば、app/DomainServicesなどにphpファイルを作成し、実装するのが良いと思います。

2
3
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
2
3