[Seasar-user:2026] Re: S2Dao へのフィードバック

Koichi Kobayashi koichik
2005年 5月 26日 (木) 00:44:21 JST


小林 (koichik) です.

On Wed, 25 May 2005 12:55:02 +0900
"Ito Yoshiichi" <[E-MAIL ADDRESS DELETED]> wrote:

> 個人的にはあまり好きじゃないです。
> 理由は DAO が S2Dao に依存してしまうから。
> アノテーションまでならなんとか許せるけど。

「依存」の意味するところ (程度) が分からないのでアレですが,

> > NotModifiedException (仮称) は SQLRuntimeExcpetion の派生で

なので,字面上の依存なら

interface ORMIndependentDao {
    void update(Emp emp);
    ・・・
}

interface S2SpecificDao extends ORMIndependentDao {
    void update(Emp emp) throws NotModifiedException;
    ・・・
}

としておいて,dicon には S2SpecificDao を記述,アプリは
ORMIndependentDao を使うようにすれば,表面的には S2Dao に
依存しないと思います.
アノテーションも S2SpecificDao にだけ書けばORMIndependentDao は
すっきりですしね.

とはいえ,これはあくまでも表面的な非依存に過ぎません.
そもそも例外をスローするというのは伊藤さんの提案ですが,
その例外の型はどんなものを想定していましたか?
それは,S2Dao とそれ以外の何かとの間で互換性 (catch する側が
DAO の実装に依存しない) があるのでしょうか?
例外を使うなら Java の標準ライブラリに含まれている例外型を
使わない限り,利用者はその実装に依存することになります.
今回の場合,適切な例外型が標準ライブラリに含まれているとは
思えないので,実装依存を避けるのは困難でしょう.
実装依存を避けるのであれば,更新件数を戻り値で受け取る方が
無難だと思います.

蛇足ですが,DAO の実装に依存しないことを過剰に意識するのは
あまり生産的ではないと思います.
# 全く意識しないのはもちろん問題外ですが.

DAO パターンが O/R マッピングフレームワークをはじめとする
データアクセス技術に依存しないためのものであることは
十分承知しているつもりですが,実際のところ,O/R マッピング
フレームワークによるセマンティクスの違いは結構大きいものがあり,
これらを DAO のレベルで隠蔽するのは大変だと思います.

例えば S2 と S2Hibernate.dao は表面的にはよく似たインタフェースを
使うように見えます.
# 意図的にそうなっているわけですが.
しかし,その違いは小さなものではありません.

S2Dao の場合,エンティティを更新するには update(EMP) のような
DAO のメソッドを呼び出すことになりますが,Hibernate では
それは不要です.単にエンティティのプロパティを更新するだけで,
トランザクションのコミット時に自動的に UPDATE 文が発行されます.
# 雑誌記事などで明示的に Session#update() を呼び出しているのは
# たいてい間違いです.
S2Hibernate.dao にも update(EMP) を定義することはできますが,
それは S2Dao の update(EMP) とは意味 (用途) が違うのです.

さらに,関連が絡んできた場合の違いもあります.
いわゆる親子関連の場合,Hibernate ではエンティティ間に関連を
設定するだけで自動的に INSERT が発行されます (マッピングで
そのように指定してあれば).
同じく関連から取り除くだけで DELETE が発行されます.
しかし,S2Dao では明示的に insert() / delete() を呼び出す必要が
あります.

このような違いは,Hibernate は S2Dao よりも RDB を隠蔽しようと
しているためにもたらされます.
私は使ったことがないので知りませんが,EOF や Cayenne など,
Hibernate 以上にRDB を隠蔽する方向 (らしい) の O/R マッピング
フレームワークではさらに大きな違いがある可能性もあるでしょう.

このような違いを DAO で吸収するというのは,私には効率的な考えには
思えません.いろいろな DAO 実装で必要になる操作の最小公倍数を
実装しないといけないと思えるからです.
例えばせっかく Hibernate を使っているのに DAO の update(EMP) を
明示的に呼び出して,それなのにその update(EMP) は何もしないように
実装するなど.

もし O/R マッピングフレームワークに依存しないことが与件であるなら,
DAO の上位に抽象レイヤを作る方がより適当ではないかと思います.
このレイヤには CRUD よりも高い水準 (抽象度) でエンティティを
操作するためのインタフェースを定義し,その実装は S2Dao や
S2Hibernate.dao などそれぞれに適した方法で DAO を利用するという具合.

もっとも,DAO や O/R マッピングフレームワークに依存しすぎないことの
メリットが十分にあるとは思えないので,私ならある程度割り切った形で
DAO の実装を選択して,それらしく使うと思います.


-- 
<signature>
    <name>Koichi Kobayashi</name>
    <e-mail>[E-MAIL ADDRESS DELETED]</e-mail>
</signature>




Seasar-user メーリングリストの案内