2
0

More than 1 year has passed since last update.

ValueObjectについてまとめてみた

Last updated at Posted at 2022-12-08

案件の中で、Value Objectを使用している箇所がいくつかあったのでまとめました。

Value Object(バリューオブジェクト) とは、

  • 値をクラスにすること
  • 値を変更したくなったら、バリューオブジェクトごと置き換えること
  • どの箇所からでも再利用できること(バリューオブジェクト内のデータを使うので、データの値を担保できる)

と自分は認識しています。

例として、Userモデルを挙げます。

Userモデル
id
name
tel

nameはその人の名前を表すものなので、バリューオブジェクトにする必要はないと思います。
下記あたりが、バリューオブジェクトにしやすいものと思います。

  • CRUDするときに、変な値で登録させたくないもの
  • typeが存在するもの(性別や、血液型など)

例として、Userモデルの中の、telをバリューオブジェクトにしてみます。

<?php

class Tel
{
    const DEFAULT_TEL = '00000000000';

    /** @var string */
    private $tel;

    /** @param string $tel */
    public function __construct(string $tel)
    {
        // 数字以外の入力だったらエラー出すとか、文字数制限とか
        if(xxxx){
           // throw Exception 
        }
        $this->tel = $tel;
    }

    /* @return string */
    public function getValue(): string
    {
        return $this->tel;
    }
}

このようになりました。telをクラス化しています。

値をクラス化することによって、Telをインスタンス化した時に、意図しない値が入るのを防ぐことができます。
意図しない値が入った場合例外を投げるので、エラー原因の特定につながります。

使い方

CRUD処理時など

User::register(
    'test_name',
    new Tel('090xxxxxxxx'),
    ....
)

これにより、new Tel('aaaaaa')と 意図しない値が入ってもエラーで弾くことができます。

引数として使うときなど

public function findFirstByTel(Tel $tel)
{
return User::where('tel', $tel->getValue())
    ->get()
    ->first();
}

バリューオブジェクトを呼び出すとき

(new Tel('00000000000'))->getValue();

コレだとピンとこないので、

例えばUserモデルをモデリングしてみます(言葉合ってるかわからないです)

class UserEntity
{
    private ?int $id;
    private string $name;
    private Tel $tel;

    public function __construct(
        $id,
        $name,
        $tel
    ) {
        $this->id = $id;
        $this->name = $name;
        $this->tel = new Tel($tel);
    }

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getTel(): Tel
    {
        return $this->tel;
    }
}

$entity = new UserEntity(null,'test_name','09012345678');

var_dump($entity->getTel()->getValue());

--> 09012345678

のような形で値を取ることができます。

この辺、DDDとも絡んでる気がするのですが、解釈人それぞれなのでこれ以上は追求しないです。(個人の感想です)

参考資料

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