値オブジェクトについて

2020-02-17

なにこれ

ドメイン駆動設計入門の自分用まとめ

値オブジェクトとは?

ドメインオブジェクトの1種。 システム固有の値を表現するためのオブジェクト。

例えば商品番号をS-123456-1みたいに表現する場合、普通にプログラミングするとstringとして定義する。
しかし、S, 123456, 1のそれぞれの意味はコードでは表現されず、この番号の意味を理解するのに有識者にヒアリングするしか無い。
また、S-1-1みたいに真ん中の数値は桁の増減をしても良いのか分からない。

そういったドメイン知識(自分的には業務知識と置き換える)をコードで表現するもの。
ガバガバだけど以下みたいなクラスを作ると商品番号の各数字の意味がわかるよってはなし。

<?php
declare(strict_types=1);

class ItemCode
{
    protected $productType;
    protected $branch;
    protected $lot;

    public __constructor(string $productType, string $branch, string $lot)
    {
        if (!in_array($productType, ['S', 'O'])) throw new Exception('不正なproductTypeです');
        if (strlen($branch) == 6) throw new Exception('branchの桁数が不正です');
        if ((int)$lot < 1) throw new Exception('lotは1以上を登録する必要があります');

        $this->productType = $productType,
        $this->branch = $branch,
        $this->lot = $lot
    }

    public function getItemCode()
    {
        return $this->productType . '-' . $this->branch . '-' . $this->lot;
    }
}

これいいっすね。 本では以下にメリット有りとのことです。

  • 表現力が増す
  • 不正な値を存在させない
  • 誤った代入を防ぐ
  • ロジックの散在を防ぐ

ロジックの散在を防ぐについては補足する。
このクラスを使えばItemCodeの値のチェックが行われるから、insertもupdateも一貫した値のチェックが出来て、呼び出し元で値のチェックを行う必要がなくなる。
よってロジックの散在を防ぐことが出来る。

思い当たる大規模リファクタリングを行った記憶があるから身に染みる、、、

まとめ

値オブジェクトについては分かりやすかった。
固有の値を扱う暗黙のルールで運用している箇所は、これを導入すると新規参入のエンジニアのキャッチアップが早くなりそうですね。