BeanUtils.copyPropertiesを利用することは思考停止していないか？

Javaの「BeanUtils.copyProperties」は非常に便利な機能ですが
適切な利用が本当にされているでしょうか？

今回はEntityとDTOおよびFormのパターンについて語りたいと思います。
※DTOだけデザインパターンなのにこの名称で語られるのに違和感がありますが・・・

EntityとDTOおよびFormはBeanとして実装されるケースを見ます。
しかし、その理由が「BeanUtils.copyProperties」を利用したいだけになっていませんか？

例えばこんな実装

```java
class EntityBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class DtoBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class FormBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}
```

Entity、DTO、Formに同じフィールドを持てば「BeanUtils.copyProperties」を
利用することは確かにでき、便利だと思います。

しかし、よく考えてみてください。
Entity、DTO、Formは異なる実装を吸収するためにあるものではないでしょうか？

「BeanUtils.copyProperties」を利用したいがゆえに同じフィールドを持つことを
強制していないでしょうか？　そうなってしまうと変化に強くもなく、データベースの仕様を
Entity、DTO、Formの3箇所を人力で運用し続けなければならなくなります。

#DBの仕様変更でフィールド名を変更した場合
Entityのvalue -> hogeに変更しました。

```java
class EntityBean
{
    private int hoge;
    public int getHoge(){ return hoge; }
    public void setHoge(int hoge){ this.hoge = hoge; }
}

class DtoBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}

class FormBean
{
    private int value;
    public int getValue(){ return value; }
    public void setValue(int value){ this.value = value; }
}
```

これって「BeanUtils.copyProperties」を使う限りビルドは通るし
それなりに動いてしまう可能性があります。DTOとForm作っている人に(もしかしたら自分)に
伝達して、修正してもらわなければなりません。動作を維持するならテストコードも必要になります。

ここまでのコストを支払う価値ってどこにありますか？
実装ミスってませんか？

Entity、DTO、Formの3箇所に同じフィールドを持つことを強制する(できる)のであれば
実装としては継承が適切です。

```java
class EntityBean
{
    private int hoge;
    public int getHoge(){ return hoge; }
    public void setHoge(int hoge){ this.hoge = hoge; }
}

class DtoBean extends EntityBean
{
}

class FormBean extends DtoBean
{
}
```

同じフィールドを持つことを担保できますし、変更があればコードレベルで
変わってくるので、ビルド時のエラーに気づけます。

継承しているので、プロパティを削りたければアップキャストすれば実現可能になり
「BeanUtils.copyProperties」を使う必要は全くありません。

でもEntity、DTO、Formの3箇所に同じフィールドを持つというのは、そもそもの目的を潰していませんか？ 

# 本当にやりたいことはこういうことのはず。

```java
class EntityBean
{
    // Entityでは日付を日付型で持つ
    private DateTime date;
    public DateTime getDate(){ return date; }
    public void setDate(DateTime date){ this.date = date; }
}

class DtoBean
{
    // DTOでは日付を文字列型で持つ
    private String date;
    public String getDate(){ return date; }
    public void String(String date){ this.date = date; }
}

class FormBean
{
    // Formでは日付を年月日別で持つ
    private String year;
    private String month;
    private String day;
}
```

「Entity、DTO、Form」がそれぞれ異なる実装を持つ可能性があるからこそ
分けるのであって、同じ実装が前提になっていたら何の意味もないのです。
「BeanUtils.copyProperties」を使う限り、抽象度は低く何の備えにもなっていません。

そもそもですが、「Entity」と「Form」の変換は誰が担うべきなんでしょうか？
「BeanUtils.copyProperties」を使うことで責任をうやむやにしていませんか？

ちなみに上記の例に限って場合「DTO」って誰得の何の役割を持つのでしょうか？
私は不要だと考えます。DTOは複数のEntityと絡みがない限りは必要ないのです。

本当は「Entity」と「Form」の変換の役割に担う別の人が必要になります。

```java
class EntityBean
{
    // Entityでは日付を日付型で持つ
    private DateTime date;
    public DateTime getDate(){ return date; }
    public void setDate(DateTime date){ this.date = date; }
}

class Converter
{
   // 相互に変換するメソッドを用意してこいつが責任を負う
   public static EntityBean convert(FormBean form) ... 実装は割愛
   public static FormBean convert(EntityBean form) ... 実装は割愛
}

class FormBean
{
    // Formでは日付を年月日別で持つ
    private String year;
    private String month;
    private String day;
}
```

「Converter」の中で、「BeanUtils.copyProperties」を使うのであれば
抽象度は保たれていると思います。


Entity、DTO、Formの3箇所に同じフィールドを手動で作成してかつ
それを設計上の前提条件として「BeanUtils.copyProperties」を利用している
ケースはみなさんの周りにはないでしょうか？

本当にそれって正しいのか？　私は疑問に思います。
ご意見ご感想お待ちしております。