2010年03月01日

ValueObjectとDTOって何が違うの?

BlogPaintValueObjectとDTO
アプリケーションレイヤー(アーキテクトの階層)の疎密度を限りなく疎にしようと考えた場合、レイヤー間の伝達は"構造をもった値"のやり取りが最適です。構造を持った値と言えばDTO(Data Transfer Object)が一般的かと思うが、たまにValueObjectなる言葉が浮上する。その違いについて今日は語ってみる。

構造を持った値
具体的に書くとこうだ。

[Serializable]
public class CustomerDTO
{
    public string Id { get; set; }
    public string Name { get; set; }
}

なんてことない、値を保持する為だけのクラスです。

DTO
上のコードはまさにDTOなんですが、値をまとめて受け渡すことのみを目的としたクラス。Serializable属性は、レイヤーが異なるPCに分かれてもSoap通信を用いてシリアライズ化して送信できるといった印です。
※Serializable属性はBinaryFormatter、XmlSerializer、SoapFormatterなどと合わせて調べてみましょう。

ValueObject
(javaでEJB(Enterprise Java Beans)とかしてるとお馴染みのValeObjectですが、)
ValueObjectの場合は"不変である"という思想が必要となります。
先ほどのコードをValueObjectに書き換えるとこうだ。

[Serializable]
public class CustomerVO
{
    public string Id { get; private set; }
    public string Name { get; private set; }

    public CustomerVO(string id, string name)
    {
        this.Id = id;
        this.Name = name;
    }
}

解説すると、インスタンスコンストラクタでプロパティを初期化し、プロパティの変更(set)は外から出来ないようにprivateにした。
ちょっぴりめんどくさいコーディングですが、"途中で値が変わらない為、スレッドセーフである。"といった利点があります。

Soap通信は試していませんが、MSDNでリフレクション辺りを見るとリフレクションではprivateのプロパティでも値の設定は可能ということでこのVOはDTOとしても機能しそうです。

VOの現実
VOの現実を現場レベルで見ると、"データアクセス層で作ったVOにビジネスロジック層で算出した結果を追加したい"など良くあることで、その場合に新しいコンストラクタを用意していくと結構面倒になる。
しかも、非同期で複数スレッドからVOを触ることもめったにないので、妥協して後から設定可能な"public set"が増えていき、コンストラクタとの切り分けもわからなくなってくるので"デフォルトコンストラクタとget、set可能なプロパティ"=全部DTOでいーじゃん的なノリになる。
そういう経緯の現場も数多く、気付けばVOとDTOって一緒みたいな感じになっていったのではないか?と推測している。

まとめ
DTOは、データ転送を目的とした値保持オブジェクトのことである。
VOは、不変でスレッドセーフを保証した値保持オブジェクトである。
値保持オブジェクトといった点で似たものであるが、"シリアライズ化(=復元可能な転送データ化)"や"スレッドセーフ対策"といった先駆者のイディオム(思考(小規模))を理解し使いこなすべし。



the_k3 at 04:11│Comments(3)TrackBack(0)アーキテクチャー 

トラックバックURL

この記事へのコメント

1. Posted by back   2010年03月02日 02:20
寝る直前です。

今でもこのDTOとVOには違和感を覚えるわけであります。

その昔、DCOM(VB6.0)で開発していて完成間近になったので本番環境で動かしたら、激遅・・・。でプロトコルアナライザーまで持ち出して調べた結果、
A(a1, a2, a3);
B(b1, b2, b3);
C(c1, c2, c3);
と延々と関数を呼び出して画面表示してたので即改造と相成ったわけであります(ちなみにここでbackfireが登場します)。

 しかし、どう修正したかというと
ABC(a1, a2, a3, b1, b2, b3, c1, c2, c3);
最高30個の引数というとんでもない改造をしました(顧客指示です)。でもコール一発で情報が手に入るので、通信オーバーヘッドがなくなり、へぇーという速度まで回復しました。

 こんな反省からこのDTOとかVOは生まれたのかなと考えるのであります。

 そうそう、本番環境というのはタイ(国)から9600bpsでリモート呼び出しという、今では想像もつかない環境です。カットオーバーまで付き合いませんでしたが、今ではこのVOとかDTOとかがきっとタイと日本の間を飛び交っているのでしょう(刷新されて)。

では、おやすみなさい。
2. Posted by longhorn   2010年03月02日 23:35
5 mail見てきました。
longhorn(前回セミナー受講者ですw)

ちなみに私も76世代です。
javaの仕事がほとんどで、
上手くコメント出来ないかもしてませんが、
C#のためになる記事楽しみにしてまーす。

3. Posted by ザ・ケイ   2010年03月03日 21:01
>backさん
なるほど。JavaのカンファレンスとかでもVOを利用した場合は速度の改善が~みたいな記事が良くありますね(グラフだけ見て検証の中身は読み飛ばしてましたが・・・)。
ボクも違和感があって何年も「どうやったらもっと簡単な入れ物ができるかな?」と考え続けてます。

>loghornさん
セミナー中々良かったですね。
初歩とマニアックな内容を中心にお贈りする予定なので、皆さんの勉強会チームの補完的な役割になれればと想います。
ボク自身もC#は急速勉強中ですので一緒に頑張りましょう!

コメントする

名前
URL
 
  絵文字