ORMへの批判

2012年5月8日

数ヶ月前にロンドンで開催されたQConカンファレンスに参加した際、あらゆる講演でオブジェクトリレーショナルマッピング(ORM)ツールに関する皮肉な発言が目立ちました。講演者に送られたカンファレンスのメールをもっと注意深く読むべきだったのでしょう。恐らく、45分おきにORMを酷評するよう指示する内容が記載されていたはずです。しかし、お分かりの通り、私はこのORMへの批判に反論したいと思っています。なぜなら、その多くは不当だと考えるからです。

ORMに対する批判を要約すると、複雑であり、リレーショナルデータストアに対する漏れのある抽象化しか提供しないというものです。その複雑さから、厳しい学習曲線が伴い、多くの場合、ORMを使用するシステムはパフォーマンスが悪くなります。これは、基盤となるデータベースとのナイーブなやり取りが原因であることがよくあります。

これらの批判には多くの真実が含まれていますが、重要な文脈が欠けています。オブジェクトリレーショナルマッピングの問題は難しいのです。本質的には、リレーショナルデータベース内のデータとメモリ内のデータの2つの全く異なる表現を同期させる作業です。これは通常オブジェクトリレーショナルマッピングと呼ばれていますが、実際にはオブジェクトとは何の関係もありません。正確には、メモリ内/リレーショナルマッピングの問題と呼ぶべきでしょう。なぜなら、RDBMSを任意のメモリ内データ構造にマッピングする場合にも当てはまるからです。メモリ内データ構造はリレーショナルモデルよりもはるかに柔軟性が高いため、効果的にプログラミングするために、ほとんどの人はより多様なメモリ内構造を使用したいと考えており、そのためデータベースへのマッピングという課題に直面することになります。

一方の側で行われた変更をもう一方の側にマッピングする必要があるため、マッピングはさらに複雑になります。さらに、複数の人が同時にデータベースにアクセスして変更を加えることができるため、複雑さが増します。ORMはトランザクションだけに頼ることができないため、この同時実行性を処理する必要があります。ほとんどの場合、メモリ内のデータを操作している間、トランザクションを開いたままにしておくことはできません。

多くの人がORMについて行っているような批判をするのであれば、代替案を提示する必要があると思います。ORMの代わりに何をするのでしょうか?私が通常耳にする安易な批判はこれを無視しています。なぜなら、ここからが厄介になるからです。基本的には、問題を異なる(そしてより良い)方法で解決するか、問題を回避するかの2つの戦略に帰着します。これらの戦略にはどちらも大きな欠点があります。

より良い解決策

一部の批判者を聞いていると、現代のソフトウェア開発者にとって最善の策は独自のORMを開発することだと考えがちです。HibernateやActive Recordのようなツールは単なる肥大化したソフトウェアになってしまったため、独自の軽量な代替案を考案すべきだという含みがあります。肥大化したソフトウェアについて何度も文句を言ってきましたが、ORMは本当にそれに当てはまりません。そして、私はこのことを苦い記憶とともに述べています。90年代の多くは、プロジェクトが次々と独自のフレームワークを作成することでオブジェクトリレーショナルマッピングの問題に対処しているのを見てきました。それは常に人々が想像していたよりもはるかに困難でした。通常は、フレームワークに深くコミットするのに十分な初期の成功を収め、しばらくしてから沼にはまっていることに気づくのです。ここで、テッド・ニューアードの有名な言葉「オブジェクトリレーショナルマッピングはコンピュータサイエンスのベトナム戦争だ[1]」に非常に共感します。

広く利用可能なオープンソースのORM(iBatis、Hibernate、Active Recordなど)は、この問題を大きく解決しました[2]。確かに、これらは使用するのに簡単なツールではありません。前述のように、根本的な問題は難しいのですが、それらのすべてを自分で作成する必要はありません(その恐怖、その恐怖)。ORMの使用をどれだけ嫌っても、私の言葉を信じてください。それを使う方が良いのです。

ORMに対する不満の多くは、過剰な期待によるものだと感じることがよくあります。多くの人がリレーショナルデータベースを「屋根裏部屋に閉じ込められ、誰も話したくない狂ったおばさんのようだ」と扱います[3]。この考え方では、メモリ内データ構造だけを扱いたいと考えており、ORMにデータベースの処理を任せたいと考えています。この考え方は、小規模なアプリケーションや負荷では機能しますが、状況が困難になるとすぐに破綻します。本質的に、ORMは約80〜90%のマッピング問題を処理できますが、残りの部分は、リレーショナルデータベースの仕組みを本当に理解している人が注意深く作業する必要があります。

ここで、ORMは漏れのある抽象化であるという批判が出てきます。これは事実ですが、ORMを避ける理由には必ずしもなりません。リレーショナルデータベースへのマッピングには、多くの繰り返し作業と定型コードが含まれます。その80%を回避できるフレームワークは、たとえ80%だけだとしても価値があります。問題は、それが100%ではないのに100%だと装っている私の側にあります。Active Recordで有名なデビッド・ハイネマイヤー・ハンソンは、リレーショナルデータベースをバックエンドとするアプリケーションを作成するなら、リレーショナルデータベースの仕組みを熟知する必要があると常に主張しています。Active Recordはこの点を考慮して設計されており、退屈な作業は処理しますが、必要に応じてSQLで作業できるようにマンホールを提供します。これは、ORMが果たすべき役割について考える上で、はるかに優れたアプローチです。

ORMが果たすべき役割についてのこのより限定的な期待には、結果があります。ORMに合わせるために、オブジェクトモデルをよりリレーショナルなものにするように強制されるという不満を聞くことがよくあります。実際、これはリレーショナルデータベースを使用する際の避けられない結果だと思います。メモリ内モデルをよりリレーショナルにするか、マッピングコードを複雑にするかのどちらかです。オブジェクトリレーショナルマッピングを簡素化するために、よりリレーショナルなドメインモデルを持つことは完全に合理的だと思います[4]。これは、常にリレーショナルモデルに厳密に従うべきだという意味ではありませんが、ドメインモデルの設計の一部としてマッピングの複雑さを考慮に入れる必要があるという意味です。

では、自分で何かをするのではなく、常に既存のORMを使用するべきだと言っているのでしょうか?「常に」と言うことを避けることを学びました。思い浮かぶ例外の1つは、データベースから読み取るだけの場合です。ORMは双方向マッピングを処理する必要があるため、複雑です。単方向の問題は、特にニーズがあまり複雑ではなく、SQLに精通している場合は、はるかに簡単に処理できます。これはCQRSの主張の1つです。

そのため、ほとんどの場合、マッピングは複雑な問題であり、アジアでの陸戦を開始するよりも、確かに複雑なツールを使用する方が良いでしょう。しかし、前述した2番目の代替案があります。問題を回避できますか?

問題の回避

マッピングの問題を回避するには、2つの選択肢があります。メモリ内でリレーショナルモデルを使用するか、データベースで使用しないかのどちらかです。

メモリ内でリレーショナルモデルを使用することは、基本的にアプリケーション全体を通してリレーションの観点からプログラミングすることを意味します。多くの点で、これは90年代のCRUDツールが提供していたものです。データ画面との間でデータを送受信する場合、またはロジックがSQLクエリでうまく表現されているアプリケーションの場合、非常にうまく機能します。このアプローチに適した問題もあり、可能であればそうするべきです。しかし、その欠点は、多くの場合不可能だということです。

ディスク上にリレーショナルデータベースを使用しないとなると、新しいチャンピオンと古い記憶が大量に湧き上がってきます。90年代には、私たち(私も含めて)の多くは、オブジェクトデータベースがディスク上のリレーションを排除することで問題を解決すると考えていました。それがどのように終わったかは皆さんご存じでしょう。しかし、今ではNoSQLデータベースという新しい仲間がいます。これにより、ORMの泥沼を回避し、データストレージを驚かせることができるのでしょうか?

お分かりかもしれませんが、NoSQLは非常に真剣に受け止めるべき技術だと考えています。アプリケーションの問題が、アグリゲートやグラフなどのNoSQLデータモデルにうまくマッピングされる場合は、マッピングの厄介さを完全に回避できます。実際、これはチームがNoSQLソリューションを選択する理由としてよく聞かれるものです。これは、私が考えるに実行可能な方法です。そのため、NoSQLシステムの理解を深めることに関心があります。しかし、それでも、アプリケーションモデルとNoSQLデータモデルの適合性が良好な場合にのみ機能します。すべての問題が技術的にNoSQLデータベースに適しているわけではありません。そしてもちろん、リレーショナルモデルに縛られている状況も多くあります。乗り越えられない企業標準である場合もあれば、未成熟な技術のリスクを同僚に納得させることができない場合もあります。この場合、マッピングの問題を回避することはできません。

そのため、ORMはほとんどのエンタープライズアプリケーションにとって非常に現実的な問題に対処するのに役立ちます。確かに、ORMは誤用されることも多く、場合によっては根本的な問題を回避することもできます。美しいツールではありませんが、それらが取り組む問題も決して心地よいものではありません。ORMはもう少し敬意と理解に値すると思います。

注記

1: ベトナム戦争の比喩との間で深い葛藤を感じていることを告白しなければなりません。あるレベルでは、厄介な技術を戦争に例えることで、ソフトウェア開発の問題を哀れにも誇張しているように見えます。プログラミングは厄介かもしれませんが、それでも比較的快適な椅子に座っており、通常はエアコンがあり、バグ探しに銃弾が飛んでくることはありません。しかし、別のレベルでは、この表現は、沼に引きずり込まれる感覚に確かに共鳴します。

2: TOPLinkやKodoなどの商用ORMもありました。しかし、オープンソースツールのアクセシビリティにより、それらが支配的になりました。

3: この表現があまりにも気に入っているので、再利用せざるを得ません。

4: 実際、多くの場合、振る舞いの豊富なドメインモデルを構築することではなく、単にシンプルなオブジェクトでラップされたリレーショナルテーブルであるRow Data Gatewaysを使用することを考えるべきです。