Open8

ChatGPTと会話しながらドメイン駆動設計に入門する

Fendo181Fendo181

参考資料

ChatGPTと学ぶ前にDDD(ドメイン駆動設計)に関わる素晴らしい記事を先に貼っておきます。

あくまでもChatGPTは補助で、メインはこれらの記事のように書籍をよみながら、手を動かして理解した方が良いと思います。

Fendo181Fendo181

はじめに

この記事(scrap)はOpenAI社が提供するChatGPTと対話しながら、ドメイン駆動設計に入門をする際に要点を絞り、素早く学習ができるのか?の実験記事です。

尚、利用するChatGPTは無料枠で使える ChatGPT-3.5を利用しています。

著者の背景

  • https://scrapbox.io/fendo181/profile
  • PHPをメインに6年ぐらい書いている。
  • ドメイン駆動設計は名前は聞いた事があるが、全然理解してない。アーキテクチャのパターンの一種(?)かなと思っている
  • ドメイン駆動設計を理解するにあたって事前にGoFのデザインパターンについてはざっくり学んだ。使いこなせているのか?と言われるとそうでもない。
  • 業務で関わるリポジトリがドメイン駆動設計に基づいて管理されているので今の内に概念と活用方法について理解したい

これ以降出てくるサンプルコードはPHPになりますので、ご了承ください。

また、実際に出力されているコードの動作確認はしてないです。
あくまでも実験的な記事なので、コードの品質や変数名が明らかに変なもの意外は、特に手を加えずそのまま出力しています。

Fendo181Fendo181

ここから実際にChatGPTと会話しながらドメイン駆動設計に入門していきます。


Prompt: ドメイン駆動設計とはなにか、PHPのサンプルコードを使って教えてください。

Answer

ドメイン駆動設計(Domain-Driven Design, DDD)は、ソフトウェアの設計手法の一つで、ビジネスドメインを中心に設計を行い、そのビジネスルールを表現することを重視します。DDDは、ドメインを深く理解し、そのドメインに適したモデルを構築することで、ソフトウェアの品質を向上させ、保守性を高めることができます。

以下に、簡単なPHPのサンプルコードを使用して、DDDの基本的な概念を紹介します。

例として、ユーザー登録を行うアプリケーションを考えます。まずは、ドメインオブジェクトを定義します。

<?php

class User
{
    private $id;
    private $name;
    private $email;
    private $password;
    
    public function __construct(string $name, string $email, string $password)
    {
        $this->id = uniqid();
        $this->name = $name;
        $this->email = $email;
        $this->password = $password;
    }
    
    public function getId(): string
    {
        return $this->id;
    }
    
    public function getName(): string
    {
        return $this->name;
    }
    
    public function getEmail(): string
    {
        return $this->email;
    }
    
    public function getPassword(): string
    {
        return $this->password;
    }
}

上記のコードでは、Userというドメインオブジェクトを定義しています。このオブジェクトには、ユーザーのID、名前、メールアドレス、パスワードを格納するプロパティが定義されています。また、コンストラクタでこれらの値を初期化しています。

次に、ユーザーを登録するためのリポジトリを定義します。

<?php

interface UserRepository
{
    public function save(User $user): void;
}

上記のコードでは、UserRepositoryというインターフェースを定義しています。
このインターフェースには、saveというメソッドが定義されています。このメソッドは、Userオブジェクトを引数に取り、ユーザーを保存するために実装されます。

最後に、ユーザーを登録するためのアプリケーションサービスを定義します。

<?php

class UserService
{
    private $userRepository;
    
    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }
    
    public function registerUser(string $name, string $email, string $password): void
    {
        $user = new User($name, $email, $password);
        $this->userRepository->save($user)
    }
}

上記のコードでは、UserServiceというアプリケーションサービスを定義しています。
このサービスには、registerUserというメソッドが定義されています。このメソッドは、引数としてユーザーの名前、メールアドレス、パスワードを受け取り、Userオブジェクトを生成して、UserRepositoryを使用して保存します。

以上のように、DDDでは、ビジネスルールを表現するドメインオブジェクト、それらのドメインオブジェクトを永続化するリポジトリ、そしてそれらのドメインオブジェクトを操作するアプリケーションサービスを定義することが重要です
これにより、ビジネスドメインを中心に設計を行い、保守性の高いソフトウェアを構築することができます。

Fendo181Fendo181

Prompt: 素晴らしい説明ですね。ありがとうございます。ドメイン駆動設計における重要なポイントを教えてください。

Answer:

以下は、ドメイン駆動設計における重要なポイントのいくつかです。

  • (1)ビジネスドメインを中心に設計を行うことが重要です。ドメインの知識を深く理解し、それを反映した設計を行うことが、保守性の高いソフトウェアを実現するために重要です。

  • (2)ビジネスルールを表現するドメインオブジェクトを設計し、それらのオブジェクトを操作するアプリケーションサービスを設計します。また、それらのオブジェクトを永続化するリポジトリも設計します。

  • (3)オブジェクト指向の原則を忠実に守ります。例えば、単一責任の原則、オープン/クローズドの原則、依存性逆転の原則などが重要です。

  • (4)ドメインオブジェクトは、状態を持つことができますが、その状態を直接変更することはできません。代わりに、操作を行うメソッドを提供し、そのメソッドを通じて状態を変更します。

  • (5)ドメインオブジェクトには、不変式を定義することが重要です。不変式は、オブジェクトの状態が常に正しいことを保証するものであり、不整合が起きることを防止します。

  • (6)ドメインオブジェクトやアプリケーションサービスは、テスト可能であることが重要です。テストを行うことで、ビジネスルールが正しく実装されていることを確認できます。

以上が、ドメイン駆動設計における重要なポイントのいくつかです。

Fendo181Fendo181

Prompt: ありがとうございます!ではメリット、デメリットについても教えてください!

Answer:

ドメイン駆動設計のメリットとデメリットについて、以下にまとめます。

【メリット】

  • (1)ビジネスドメインにフォーカスした設計が可能

    • ドメイン駆動設計では、ビジネスドメインにフォーカスした設計が行えるため、ビジネス価値の高いソフトウェアを開発できます。また、ドメイン知識を深く理解している開発者と、ドメインエキスパートとのコミュニケーションを促進し、要件の明確化がしやすくなります。
  • (2)コードの保守性が向上する

    • ドメイン駆動設計では、ビジネスルールを表現するドメインオブジェクトが中心になります。このため、ビジネスルールを変更する場合には、変更が必要な箇所が限られるため、保守性が向上します。
  • (3)可読性が向上する

    • ドメイン駆動設計では、ビジネスルールを表現するオブジェクトや、それらを操作するサービスが中心になります。このため、コードがビジネスロジックにフォーカスした形で記述されるため、可読性が向上します。
  • (4)テストが容易になる

  • ドメイン駆動設計では、ビジネスルールを表現するオブジェクトや、それらを操作するサービスが中心になります。このため、テストが容易になり、テストカバレッジを高めることができます。

【デメリット】

  • (1)設計に時間がかかる

    • ドメイン駆動設計は、ビジネスドメインを深く理解した上で設計を行う必要があります。このため、設計に時間がかかることがあります。
  • (2)複雑な設計になりやすい

    • ドメイン駆動設計では、ビジネスルールを表現するオブジェクトや、それらを操作するサービスが中心になります。このため、複雑な設計になりやすく、理解に時間がかかることがあります。
  • (3)開発者の知識やスキルに依存する

    • ドメイン駆動設計では、ドメイン知識を深く理解した開発者や、オブジェクト指向の設計スキルを持った開発者が必要となります。このため、開発者の知識やスキルに依存するため、開発者の人員確保や育成に時間やコストがかかることがあります。
  • (4)プロジェクトの規模によっては過剰な設計になることがある

    • ドメイン駆動設計は、ビジネスドメインにフォーカスした設計を行うことが目的です。しかし、プロジェクトの規模が小さい場合や、ビジネスドメインが単純な場合は、過剰な設計になる可能性があります。
  • (5)複数人で開発する場合のコミュニケーションコストが高い

    • ドメイン駆動設計では、ビジネスドメインにフォーカスした設計が行えるため、複数の開発者が関与する場合でも設計の統一性を保つことができます。しかし、設計についてのコミュニケーションコストが高くなるため、適切なコミュニケーションが必要となります。

以上が、ドメイン駆動設計のメリットとデメリットです。プロジェクトの要件や状況に合わせて、ドメイン駆動設計を採用するかどうかを判断することが重要です。

Fendo181Fendo181

Prompt: 素晴らしい説明ありがとうございました。また何かわからない事があれば質問させてください!

Answer:

どういたしまして。何かありましたら、いつでもお気軽にお問い合わせください。お力になれるよう、最善を尽くします。

Fendo181Fendo181

まとめ

ChatGPTに質問して上記の回答を得て理解するまでが大体15分程度でした。
そして、そのやり取りを載せながら自分でも理解を深める為にこの、zennのScrapを使ってアウトプットしながらまとめるのに大体40~50分程度かかったので、大体1時間ぐらいでChatGPTと会話しながらドメイン駆動設計に入門...できたのかなと思います。

ただ、自分はドメイン駆動設計をまだちゃんと理解できてないのと、実際にDDDを意識してコードを書いた経験がすくないので自信はあるのか?と言われると、「う〜〜ん」というのが今の感想です。

例えば以下の説明であった「不変式を定義する」が一体どんな実装なのかはわからなかったです。

(5)ドメインオブジェクトには、不変式を定義することが重要です。不変式は、オブジェクトの状態が常に正しいことを保証するものであり、不整合が起きることを防止します。

また、オブジェクト指向の原則の話も上がっていたので、ここはある程度PHPや他の言語でも概念を触れておくと理解がしやすいのかなぁ...と思いました。

ただ、メリットとデメリットについて質問をすると、事前に「参考資料」で載せた記事に出てくる話題が要点に絞って答えが返ってきてよかったです。

そんな感じで「ChatGPTと会話しながらドメイン駆動設計に入門する」という、話題のキーワードを盛り込んだ実験記事になったのですが、個人的には最初の導入として良いのではないかなと思いました。

ここまで読んでくれてありがとうございます!

そして僕はこれからドメイン駆動設計をより深く理解する為に「ドメイン駆動設計入門 ボトムアップでわかる!ドメイン駆動設計の基本」と「エリック・エヴァンスのドメイン駆動設計」を両手に持ちながら、モデリングのジャングルへ潜り込んで行きたいと思います...!!

おわり