主旨
オブジェクト指向エクササイズなどでは、プリミティブ型(int, stringなど)をクラスでラップすることを勧める記事をよく見る。
本記事では、プリミティブをラップすることで、どんなことに有効なのかを説明してゆく。
結論
①業務知識(=ドメイン)を含むビジネスロジックが、コードのクライアント側に漏れ出すことを防ぐため。
②ロジックの重複を防ぐため。
具体例
上記の図を用いて、年度を例にして説明をする。
ビジネスロジックを組み立てる際に、特定の年度における「年度開始日」と「年度終了日」が必要になったと仮定する。
このような状況において、年度をint型で扱っている場合に、上記の日付を求めるメソッドは、年度を扱う側に定義することとなる。
いけてないポイント①:メソッドを定義する場所
メソッドが定義されている場所は、年度から求めた日付を扱って、より高度なビジネスロジックを組み立てなくてはならない場所である。
そのような場所に、たかが年度における変換ロジックを記載すると、全体の見通しが悪くなる。
いけてないポイント②:ロジック重複の可能性
別のプログラムでも同様に、「年度開始日」と「年度終了日」が必要になったと仮定しよう。
同じファイル内にビジネスロジックがあるなら問題はないが、別のファイルであればどうであろう。
安易な解決方法は、ロジックを重複することである。別な方法としては、publicでstaticなメソッドにすることである。
どちらも、エレガントでない。
プリミティブ型をクラスでラップする
年度の値であるint型に対して、クラスでラップすると、上記の問題が一度に解決する。
メソッドを定義する場所については、これ以上なく適切な場所になる。(年度クラスにおける開始日、終了日であるため。)
また、年度クラスを使用する限り、ロジックの重複もあり得ない。
まとめ
プリミティブ型では、データに対しての振る舞いが足りないことがよくある。
エンタープライズアプリケーションではそれがより顕著である。
そこで、プリミティブ型をクラスでラップすることで、特定のロジックを綺麗にカプセル化できることになる。
その結果、ドメインが外に漏れ出すことでのコードの重複や、その値を使用する側のコードでの可読性のアップ、そして、再利用性があることを学んだ。
上記が、DDDであるところのValueObjectとなる。