2010.12.23 追記
本エントリの続編となる「実装編」のブログを書きました。
こちらも合わせて読んでみてください。
O/Rマッピングツールに対する誤解をときたい -実装編 Part1- - give IT a try
本文にコメントすると泥沼に巻き込まれそうなので、ここに書いておきます。。。
http://el.jibun.atmarkit.co.jp/g1sys/2010/05/post-2d1b.html
なんかこのコラムのコメントを読んでいると、「O/Rマッピングツール(ORM)はSQLを書きたくない開発者のためのツールだ」と思われているような感じを受けます。
おいらはこれまでORMを使った開発プロジェクトに3回参加しました。
確かに最初のプロジェクトでは「SQLを書かなくてもいいんだよ」とリーダーから説明されたような記憶があります。
しかしその発想は大きな誤解です。
ORMをそのように見ていると「SQLより効率が悪い」という議論に流れていってしまうのは必然です。
ORMはSQLで出来ることをラッピングして開発効率を上げるツールではありません。
むしろ素直にSQLでやろうとすると開発効率が落ちてしまう問題を解決するために存在するツールです。
ではその問題とは何か?
それは「インピーダンスミスマッチ問題」です。
そもそもO/RマッピングツールのO/Rって何でしょう?
はい、ご存知ですよね。ObjectとRelationalです。
オブジェクトとリレーショナルデータベース間をマッピングルするツール、つまりオブジェクト指向とリレーショナル理論の橋渡しを行うツール、という名前がつけられています。
もしもORMが「SQLを書きたくない人のためのツール」だったら「SQLラッピングツール」とか、そんな名前が付きそうだと思いませんか?
ここでひとつ、仮想の新規開発プロジェクトを想定します。
そのプロジェクトでは議論の結果、オブジェクト指向を採用することにしました。
(ここで「議論の結果」という部分に注目してください。盲目的にオブジェクト指向を採用したのではなく、オブジェクト指向以外の設計手法も検討したが、様々なメリットとデメリットを天秤にかけた結果、相対的にオブジェクト指向が最も優位になった、というのが前提です。つまりおいらが言いたいのは、オブジェクト指向は盲目的に採用可能な「銀の弾丸」ではない、ということです)
ユーザーのビジネスを分析し、ビジネスの構成要素をクラスとして抽出しました。
クラスとクラスはそれぞれ1対1、1対多、多対多といった関連を持っています。
保守性や拡張性の点で有利なポリモーフィズムはオブジェクト指向を採用する最も大きな動機の一つです。
なので継承関係を持ったクラスもいくつか存在しています。
開発言語にはXXXが採用されました(JavaでもC#でもRubyでも何でもいいです)。
オブジェクト指向に対応している言語なので、分析段階で抽出されたオブジェクト間の関連や継承関係は簡単に実装できます。
ところが突然大きな問題が発生しました。
そのプロジェクトではリレーショナルデータベースを使うことになっていたのですが、開発言語上のオブジェクトを保存したり、取り出したりしようとすると、テーブル設計やロジックが非常に複雑になってしまうことが分かりました。
リレーショナルデータベース上では継承という概念が存在しないので(たしか)、継承関係にあるクラスをどうやってテーブルに置き換えたら良いのでしょう?
もちろん、ゴリおしで実装できなくはないのですが、せっかくオブジェクト指向言語を採用してシンプルなロジックで実装できたというのに、データの出し入れ部分のロジックが複雑化してしまうのは惜しいです。
多対多の関連も開発言語上では二つのクラスで実現できますが、データベース上では3つのテーブルが必要になります。
なので、1クラス=1テーブルというわけにはいきません。
などなど、オブジェクト指向で設計 → オブジェクト指向言語で実装、というところまではスマートに進んだのに、データを保存したり取り出したりする部分でつまずいてしまいました。
・・・これがインピーダンスミスマッチ問題です。
つまりオブジェクト指向上のクラスとリレーショナルデータベースは互換性が無いため、バリバリのオブジェクト指向で作られたプログラムほど、データベースとのやりとりに困るわけです。
そこでO/Rマッピングツールが登場するわけです。
このツールを使えばインピーダンスミスマッチ問題に苦しみながら、独力で車輪の再発明している世界中の開発者を救うことが出来るのです。
ここでこのエントリーをもう一度最初から読んでみてください。
ね?「SQLを書きたくない人のツール」じゃないことが明らかでしょ?
そんな発想で作られたツールではないんです。
ORMを使えば複雑になりがちなデータベースとのやりとりを隠蔽してくれます。
オブジェクトをほいっとORMが提供するメソッドに渡してあげれば、そのオブジェクトがデータベースに登録されます。
一つのオブジェクトに色々なオブジェクトがぶら下がっているような場合なら、ORMが自動的に複数のテーブルにデータを登録してくれます。
逆にORMに対して、「このあいだ登録したこのオブジェクトをもう一回使いたい」と命令すれば、ひょいっとそのオブジェクトを返してくれます。
先ほどと同様、複数のテーブルにまたがって落ちているデータもORMが自動的に拾い上げてオブジェクトを再構築してくれます。
もちろん継承関係や多対多のリレーションに関してもバッチリ再現してくれます。
このようにORMを利用することでデータベースの存在を意識しなくてよくなります。
つまり開発者はオブジェクト指向プログラミングに集中できるわけです。
プログラミングのパラダイムにも一貫性が生まれます。
ちなみにORMを使ってプログラミングをしていると、データベースにデータを格納しているというより、オブジェクトを自由に冷凍保存して、自由に解凍しているような感覚になります。
こういう感覚には「オブジェクトの永続化」っていう表現がしっくりきます。
もちろん、「抽象化は開発者を楽にしてくれるが、背後にある知識を不要にするわけではない」という原則はここでも重要です。
ORMを使っていても、結局背後に存在するのはデータベースやSQLなので、これらに関する知識が不要になるわけではありません。
たとえば複雑なレポーティングクエリや大量のバッチ処理などはORMの不得意分野です。
こういう場面ではORMを使わずにSQLだけで構築した方が開発効率も実行効率も高くなります。
だから場面によって使い分ければ良いわけです。
とはいえ、その見極めをするためにはSQLとORM双方の仕組みや得意分野、不得意分野を深く理解しておく必要がありますよね?
最後に、ORMについては以下のような見方をすることもできます。
「最初からあらゆる要素をオブジェクト指向で設計、実装すると決めた新規開発システムならばORMは有力な採用候補」
「非オブジェクト指向で設計、実装されたシステムにORMはあまり向いていない」
なので、すでに存在しているデータベース上で別の新しいシステムを構築するような場合は、ORMはあまり向いていないと思います。
たとえばHibernateの場合、複数のカラムで構成される主キーを扱おうとすると色々とややこしい問題が出てきます(最近のバージョンはよく知りませんが、当時はそうでした)。
どうでしょうか?
× ORMはSQLが苦手な人を救うツール
○ ORMはオブジェクト指向を全面に採用したシステムの開発効率を上げるためのツール
ということがお分かりいただけたでしょうか?
このエントリーを読んで一人でもこれまでの誤解に気づいてくれる人がいたらうれしいです。
「そもそもオブジェクト指向の何がうれしいのか?そんなに効率を上げてくれるのか?」という根源的な疑問もあるかもしれませんが、それを語りだすとさらに話が長くなるので今回は割愛させてください。
それにしてもWEB上でこういう話を伝えるのって難しいですね。
色々頑張って書きましたが、これを読んでくれた人の大半にはおいらの頭の中にある「フィーリング」はほんの数パーセントしか伝わってないんじゃないかと思います。
以前も書きましたが、「だから一緒に開発してみましょう」と言いたくなるわけです。
特にオブジェクト指向やORMのメリットっていうのは実際にがっつり取り組んでみないと分からないと思います。
あ、そのときは「オブジェクト指向やORMを本当に理解している人」がリードしてくれることが前提です。
中途半端な理解の上に構築された「オブジェクト指向もどき」システムは、非オブジェクト指向システムよりもタチが悪くなることがあります。
オブジェクト指向を毛嫌いしている人たちは運悪くそういうシステムに当たってしまって、変なトラウマがついちゃってるんじゃないかな〜と思ったりもします。
そんなにヒドイもんならこんなに普及しませんって〜(^ -)
P.S.
インピーダンスミスマッチ問題やORMの本質に興味がある人はこの本を読んでみてください。
Hibernateを使う機会がなかったとしても、ここで説明されている理論や技術は勉強になるはずです。
ちなみにおいらがこのエントリーで書いたことの大半はこの本の第1章に詳しく書いてあります。
- 作者: Christain Bauer,Gavin Ki,倉橋央,勝嶌和彦
- 出版社/メーカー: ソフトバンク クリエイティブ
- 発売日: 2005/12/28
- メディア: 大型本
- 購入: 3人 クリック: 109回
- この商品を含むブログ (35件) を見る
参考までに本文を一部抜粋しておきます。
ORMの予想される利点は面倒なSQLから開発者を守ってくれるというものであろう。
これはオブジェクト指向開発者がSQLやリレーショナルデータベースをよく理解したがらず、SQLを厄介者と考えるだろうという視点に立っている。これに対して、筆者の考えは異なる。
筆者はORMを利用する開発者はSQLとリレーショナルモデリングに精通しているべきだと考えている。(P34)