登録日:
2025-02-02
最終更新日:
2025-03-19
Laravel に DDD の概念を取り込む
Laravel に DDD(ドメイン駆動設計)の概念を取り込むには、アーキテクチャの工夫が必要です。Laravel はもともと MVC(Model View Controller)をベースとしたフレームワークですが、DDD の概念を適用することで、よりスケーラブルで保守性の高いアプリケーションを構築できます。
DDDをLaravelに適用する際のポイント
レイヤー構成の見直し
DDDでは以下のようなレイヤー構成を採用します。 Laravel の MVC にそのまま適用するのではなく、適切にレイヤーを分割しましょう。
ドメイン層(Domain Layer)
- エンティティ(Entities)
- 値オブジェクト(Value Objects)
- ドメインサービス(Domain Services)
- 集約(Aggregates)
- リポジトリインターフェース(Repository Interface)
- アプリケーション層(Application Layer)
アプリケーションサービス(Application Services)
- DTO(Data Transfer Objects)
- インフラストラクチャ層(Infrastructure Layer)
リポジトリの実装(Eloquent など)
- 外部 API やデータベースとの接続
- プレゼンテーション層(Presentation Layer)
コントローラー(Controllers)
- リクエスト(Requests)
- ビュー(Views)
ドメイン層の実装
エンティティ
エンティティは、識別子(ID)を持ち、ビジネスルールを適用するオブジェクトです。
namespace App\Domain\Entities;
class User
{
private string $id;
private string $name;
private string $email;
public function __construct(
string $id, string $name, string $email)
{
$this->id = $id;
$this->name = $name;
$this->email = $email;
}
public function changeName(string $name): void
{
$this->name = $name;
}
public function getId(): string
{
return $this->id;
}
public function getName(): string
{
return $this->name;
}
public function getEmail(): string
{
return $this->email;
}
}
値オブジェクト
値オブジェクトは不変で、ビジネスルールをカプセル化します。
namespace App\Domain\ValueObjects;
class Email
{
private string $email;
public function __construct(string $email)
{
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
throw new \InvalidArgumentException("Invalid email");
}
$this->email = $email;
}
public function getValue(): string
{
return $this->email;
}
}
アプリケーション層
アプリケーション層では、ユースケースを実装します。
namespace App\Application\Services;
use App\Domain\Repositories\UserRepositoryInterface;
use App\Domain\Entities\User;
class UserService
{
private UserRepositoryInterface $userRepository;
public function __construct(
UserRepositoryInterface $userRepository)
{
$this->userRepository = $userRepository;
}
public function registerUser(string $name, string $email): User
{
$user = new User(uniqid(), $name, $email);
$this->userRepository->save($user);
return $user;
}
}
インフラストラクチャ層
リポジトリをEloquentを用いて実装します。
namespace App\Infrastructure\Repositories;
use App\Domain\Repositories\UserRepositoryInterface;
use App\Domain\Entities\User;
use App\Models\User as EloquentUser;
class UserRepository implements UserRepositoryInterface
{
public function save(User $user): void
{
EloquentUser::create([
'id' => $user->getId(),
'name' => $user->getName(),
'email' => $user->getEmail()
]);
}
}
コントローラー(プレゼンテーション層)
コントローラーはアプリケーション層のサービスを呼び出します。
namespace App\Http\Controllers;
use App\Application\Services\UserService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;
class UserController extends Controller
{
private UserService $userService;
public function __construct(UserService $userService)
{
$this->userService = $userService;
}
public function register(Request $request): JsonResponse
{
$user = $this->userService->registerUser(
$request->input('name'),
$request->input('email')
);
return response()->json([
'id' => $user->getId(),
'name' => $user->getName(),
'email' => $user->getEmail()
]);
}
}
まとめ
Laravel に DDD を適用するには、以下のポイントを意識すると良い。
- レイヤードアーキテクチャを採用する(ドメイン層・アプリケーション層・インフラ層・プレゼンテーション層)
- エンティティと値オブジェクトを活用して、ビジネスルールをカプセル化する
- リポジトリパターンを導入し、データアクセスの抽象化を行う
- アプリケーションサービスを通じて、ユースケース単位でビジネスロジックを実装する