LoginSignup
2
1

More than 1 year has passed since last update.

DDD初心者でも仲良くなりたい ~値オブジェクト編~

Last updated at Posted at 2023-02-26

はじめに

  • 値オブジェクトとはドメインオブジェクトの基本
  • 概念自体はシンプルで、システムに登場する金銭や単価といった値をオブジェクトとして定義するもの

PHP(Laravelで書いてみる)

ユーザーを登録する処理で、値オブジェクトを使わない場合と使った場合で比較してみます。

値オブジェクトを使わない場合の処理

UserRepository.php
class UserRepository extends BaseRepository
{
    private crateUser (string $userId, string $name) 
    {
        // 新規ユーザー作成をする処理
    }
}
UserLogic.php
class UserLogic {
    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
        $this->userRepository = $userRepository;
    }
    
    private function createUser()
    {
        $userId = 'komeda_tarou';
        $name = 'コメダ太郎';
        
        $this->userRepository->createUser($userId, $name);
    };
}

ユーザー追加のための何気ない処理を書いています。ここでいくつか気になる点をあげるとすると、createUserメソッドに渡す引数の$name$userIdの順番を間違えてしまう可能性があります。今回の場合順番を間違えたとしてもどちらも文字列のため保存されてしまいます。

また、userIdの型は今回はstring型を渡す必要がありますが、string型かint型かどうかはロジッククラスからは分かりません。これらを値オブジェクトを使って解決してみます。

値オブジェクトを使う場合の処理

まず、値オブジェクトクラスを作成します。

値オブジェクトクラス.php
class UserId
{
    private $value;
    
    public function __construct(string $value)
    {
        $this->value = $value;
    }
    
    public function getValue(): string
    {
        return $this->value;
    }
}

class Name
{
    private $value;

    public function __construct(string $value)
    {
        $this->value = $value;
    }

    public function getValue(): string
    {
        return $this->value;
    }
}

上記で作成した値オブジェクトを引数として使うことによって、値を入れ間違う危険が減ります。値オブジェクトを使うように修正してみます。

UserRepository.php
class UserRepository extends BaseRepository
{
    private crateUser (UserId $userId, Name $name) 
    {
        // 新規ユーザー作成をする処理
    }
}
UserLogic.php
class UserLogic {

    private function createUser()
    {
        $userId = new UserId('komeda_tarou');
        $name = new Name('コメダ太郎');
        
        $this->userRepository->createUser($userId, $name);
    };
}

もし$userId$nameに不正な値が入らないように制限をかけたい場合、値オブジェクトクラスの中で、制限をかけることができます。今回はコンストラクタ内に、許可しない値が渡された場合はExceptionを投げるようにしてみます。

値オブジェクトの中で、不正な値が入らないように配慮

  • 制限①: $userIdは_を含まなければならない
  • 制限②: $nameは10文字以下でなければならない
値オブジェクトクラス.php
class UserId
{
    private $value;
    
    public function __construct(string $value)
    {
        // 制限①: $userIdは`_`を含まなければならない
        if (false === strpos($value, '_')) {
            throw new Exception();
        }
        $this->value = $value;
    }
}

class Name
{
    private $value;

    public function __construct(string $value)
    {
        // 制限② $nameは10文字以下
        if (mb_strlen($value) <= 10) {
            throw new Exception();
        }
        $this->value = $value;
    }
}

それぞれの制限に対して違反する値が渡されたときは、Exceptionを返すようになりました!

最後に

値オブジェクトは「ルールを定義して、そのルールに反する操作を許容しない」ということをクラスとして定義している。

2
1
1

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
1