Spring Boot / MyBatis / Domain / Value Object

Spring Boot / MyBatis / Domain / Value Object

What is Value Object

Domain にはもう一段突っ込んだ考え方があって、それが Value Object になる。 実装的には Domain が DB のレコードに対応するのならば、 Value Object はそのカラム定義にあたる。

DB のカラム定義はその DBMS で定義された吊るしの型を使うことになる。ID でやるなら BIGINT にするかという具合。 通常の ORM ならそれを Java のプリミティブ型かそのラッパークラス、String 等の基本クラスに割り当てる。

ここをあえてそうせずに独自のクラスを定義してそれに割り当ててやろうというのが、この Value Object の設計である。 設計としては、データの意味をガチで最後まで詰め切るということである。

こうなると単なる ID も単なる ID でなくなる。ある特定のデータを識別するための特別な ID になる。 そしてそれを Java のクラスで定義することになるので、それがその用途以外に使えなくなる。ガチガチに固められる。

よくありげなのが同じ Long で定義されていた ID を取り違えてしまうとかがあるが、そんなことがおこらなくなる。

さらにクラスで定義することによりよりそのカラムの仕様を明確に記述できるようになる。 Long 型だけではかなり広い範囲を指すことになるが、クラスなのでそのアクセサに「ゼロより大」と明記できるようになる。 Java の方が SQL の DDL よりもより表現力豊かなので。

当然だが Value Object にせず、基本的な型で作っていくという選択肢もある。

Basic

このような Domain があったとする。

public class Hoge{
    private Integer v1;
    private String v2;
    private String memo;
 
    public Integer getV1(){
        return this.v1;
    }
    public void setV1(Integer v){
        this.v1 = v;
    }
 
    public String getV2(){
        return this.v2;
    }
    public void setV2(String v){
        this.v2 = v;
    }
    public String getMemo(){
        return this.memo;
    }
    public void setMemo(String v){
        this.memo = v;
    }
}

この v1, v2 を Value Object 化する。

public class HogeV1{
    private Integer value;
 
    public Integer getValue(){
        return this.value;
    }
    public void setValue(Integer value){
        this.value = value;
    }
}
public class HogeV2{
    private String value;
 
    public String getValue(){
        return this.value;
    }
    public void setValue(String value){
        this.value = value;
    }
}

2つ作った。メンバの名前はどうでもいいのだが、value に統一しておくとわかりやすい。こいつを組み込む。

public class Hoge{
    private HogeV1 v1;
    private HogeV2 v2;
    private String memo;
 
    public HogeV1 getV1(){
        return this.v1;
    }
    public void setV1(HogeV1 v){
        this.v1 = v;
    }
 
    public HogeV2 getV2(){
        return this.v2;
    }
    public void setV2(HogeV2 v){
        this.v2 = v;
    }
    public String getMemo(){
        return this.memo;
    }
    public void setMemo(String v){
        this.memo = v;
    }
}

このようになる。piyo_v1 が同じように Integer だったとしても型としてそもそも入れることができないので安全である。

java/spring/spring_boot/mybatis/domain/value_object/start.txt · 最終更新: 2021-06-27 17:30 by ore