読者です 読者をやめる 読者になる 読者になる

give IT a try

プログラミング、リモートワーク、田舎暮らし、音楽、etc.

O/Rマッピングツールに対する誤解をときたい -実装編 Part9-

Part8を読む

これまでのまとめ

当初考えていた以上に長いシリーズとなってしまったので、一度全体を振り返ってみます。
また、その後でO/Rマッピングツールを採用するかどうかの判断基準や考慮点、アンチパターンなんかも書いてみたいと思います。

これまでに書いてきたエントリの概要

O/Rマッピングツールに対する誤解をときたい
このシリーズの出発点となった「元ネタ」です。
とあるコラムの議論を読んでいて、「なんか論点がおかしいな〜」と感じたのでこのエントリを書きました。
O/RマッピングツールはSQLを書きたくない人のためのツールではなく、インピーダンスミスマッチ問題を解決するためのツールであるということを文章で説明しています。


実装編 Part1
Part1ではサンプルプログラムの仕様について説明しました。
またインピーダンスミスマッチ問題を解決する過程よりもむしろ、O/Rマッピングツールが実現する「オブジェクトの透過的な永続化」の説明に重点をおき、オブジェクト指向プログラミングやO/Rマッピングツールの有用性を理解してもらおうと考えました。


実装編 Part2
Part2ではサンプルプログラムのプログラム設計を紹介しています。
ドメインモデルのクラス設計では継承の概念が登場しています。
また、Smart UIパターンではなくUIとビジネスロジックを分離するレイヤー化アーキテクチャを選択しました。
処理シーケンスの中ではビジネスロジックの実装にポリモーフィズムを活用することを説明しています。


実装編 Part3
Part3ではUI側の実装コードを載せています。
レイヤー化アーキテクチャを採用しているため、UI側のコードには基本的に画面制御に関わるコードしか出てきません。
ビジネスロジックを実現するためにUI側でしなければならないのは、Facadeクラスのメソッドを呼び出すことだけです。


実装編 Part4
Part4ではドメインモデルクラスの実装コードを載せています。
Part2で設計した通り、書籍クラスと和書クラス、洋書クラスは継承関係にあり、「発送予定日を計算する」メソッドではポリモーフィズムが使えるようになっています。


実装編 Part5
Part5では注文Facadeクラスの実装コードを載せています。
また、ここからNHibernateを使ったコードが登場します。
Part2で説明した処理シーケンスとほぼ同じコードがFacade内で実装されており、書籍オブジェクトに対する操作にはポリモーフィズムを活用しています。
また、NHibernateを利用したおかげで、オブジェクトの保存や取得が非常に簡潔なコードで実現できています。


実装編 Part6
Part6では書籍Facadeの実装コードを通じて、NHibernateのHQLを説明しています。
HQLとSQLは「似て非なるもの」であり、HQLはデータベース上のテーブルやカラムを操作するのではなく、プログラム上のクラスやプロパティを操作していることを説明しました。


実装編 Part7
Part7ではテーブル設計やNHibernateのマッピングファイル等、データベースの設計や設定に関する説明をしています。
また、プログラム上のクラスとデータベース上のテーブルは完全には一致しないことも説明しています。(このあたりがいわゆる「インピーダンスミスマッチ」です。)


実装編 Part8
Part8ではNHibernateに関する補足説明を行いました。
Lazy Loading機能、ポリモーフィックなHQL、select節を使用するHQL、パフォーマンス問題等に遭遇したときの参考資料などを紹介しています。

O/Rマッピングツールを採用するかどうかの判断基準について

このシリーズでは「O/Rマッピングツールに対する誤解をとく」のが目的であって、O/Rマッピングツールを銀の弾丸として賞賛しようとしているのではありません。
それどころかむしろ、O/Rマッピングツールを開発業務で採用するには多くの障壁が存在すると考えています。


4〜5年前にHibernateを開発業務で使った経験から、O/Rマッピングツールを採用するかどうかの判断基準を自分なりに紹介してみたいと思います。


理想的には上記の項目がすべて「YES」になることですね。
逆に「NO」が多ければ多いほど、O/Rマッピングツールを導入したけど逆効果、ということになりかねません。
このあたりの話は元ネタの後半部分でも述べています。

O/Rマッピングツールの考慮点

続いて、O/Rマッピングツールを採用する前に十分に考慮が必要な項目を挙げてみたいと思います。
ただし、以下のようなネガティブな要素があるからといって「O/Rマッピングツールはダメだ」とすぐに結論づけないでください。
O/Rマッピングツールや他の選択肢とのメリットとデメリットを比較し、最も適切な技術を選択するバランス感覚が、技術者に求められる重要なスキルの一つなのではないでしょうか。


実行パフォーマンス
O/RマッピングツールはSQLよりも遅い」と頭から決めつけるのは危険な考え方だと思います。
例えばHibernateNHibernateにはキャッシュ機能があるので、同じオブジェクトはデータベースにクエリを発行せずに取得できたりします。
パフォーマンスを効率化するための戦略が色々と用意されていることはPart8でも述べた通りです。
また、O/RマッピングツールがSQLよりも実際に遅いケースがあったとしても、システムの要件からすると特別問題がないレベルだったりします。
さらに、開発者のスキルによってはヘタなSQLを書くよりも、ツールが出力したSQLの方が高効率ということもあるかもしれません。


ただし、実際問題としてO/Rマッピングツールのデフォルトの挙動がボトルネックになってしまうということはよくある話だと思います。
そういう問題に遭遇したときに最初から匙を投げるのではなく、Part8で紹介したような資料を使って有効なオプションを探っていく姿勢が重要だと思います。


他システムとの連携
テーブル設計をO/Rマッピングツールに最適化させた場合、状況によっては少し奇妙なテーブル設計に見えることがあるかもしれません。
O/Rマッピングツールにとっては都合が良くても、同じツールを使っていない他のシステムからそのテーブルを利用しようとすると扱いづらいということが起こりえます。
ただし、クラス設計がきれいにできていれば、自ずとテーブル設計もきれいなものになっていくはずです(たぶん)。
また、テーブルだけでなくロジックも他のシステムから再利用するのであれば、ストアドとして実装されていた方が利用しやすい、というケースもおそらくあるでしょう。


システムの寿命とO/Rマッピングツールの寿命
システム開発に関わる要素のすべてに寿命があります。
データベース、開発言語、O/Rマッピングツールにもそれぞれ寿命があるわけです。
そしてその中にシステムの寿命よりも寿命が短いものがあると、将来的に移行コストが発生します。
未来のことは誰にも分かりませんが、感覚的に言って寿命の長さは「データベース(SQL) > 開発言語 > O/Rマッピングツール」となりそうな気がします。
よって採用したO/Rマッピングツールのメンテナンスが終了し、最新のプラットフォームに対応できなくなるというリスクを事前に考慮しておいた方が良いと思います。
システムの寿命が長そうであれば、最初からSQLやストアドを使って実装したり、DAOパターンなどを使ってデータアクセス層を容易に置換できる設計を採用したりする選択肢を考える必要があります。

O/Rマッピングツールのアンチパターン

O/Rマッピングツールのアンチパターンは言わずもがな、「O/RマッピングツールはSQLを書きたくない人のためのツールだ」と誤解することだと思います。
そして、上で書いた判断基準で「NO」が多ければ多いほど、泥沼にはまっていくことになると思います。
Web上の簡単な紹介記事だけを読んで単純に「あ、良さげ」と思いこんで、採用したりすると結構痛い目を見るのではないでしょうか?


一つのテーブルを操作するだけの簡単なシナリオであれば、Web記事レベルの知識で事足りますが、実際の開発業務ではWeb記事とは比較にならないような複雑なシナリオだらけです。
SQLを書かずに楽しちゃおう」という考えしか持たずに実戦に挑んでも、すぐにツールのクセや制約という壁にぶつかって「最初からSQLを書いてた方が速かった」というオチが待っているだけだと思います。


SQLでできることをO/Rマッピングツールを使ってやろうとするなら、O/Rマッピングツールが間に入るぶん全部ムダです。
そうではなくて、「SQLじゃできないことをやりたい、だからO/Rマッピングツールを使う」という動機が必要になると思います。
ここで言う「SQLでは出来ないこと」というのは、継承やポリモーフィズムといったオブジェクト指向プログラミングのテクニックを駆使することです。

まとめのまとめ

自分の言いたいことはすでにPart7で書いています。
つまり、


O/RマッピングツールはSQLを書きたくない人のためのツール


ではなく、O/Rマッピングツールは

  • 最初からプログラムをオブジェクト指向で設計できる
  • 実装する上でもデータベースのことは気にせず、クラスやオブジェクトを操作することだけに開発者が集中できる
  • ポリモーフィズムや継承など、オブジェクト指向プログラミングのメリットを存分に活用することができる
  • 結果、プログラムの開発効率や保守性、拡張性を高めることができる


といったことを可能にしてくれるツールだということです。
O/RマッピングツールはSQLを書きたくない人のためのツール」だと思い込んでいると、「わざわざO/Rマッピングツールを使うメリットなんてない」というおかしな結論に至ってしまうのは必然です。


こうしたことはこのシリーズを通じて何度も言っていることですし、このシリーズを通して実現したかったのはネット上でよく見かける「O/Rマッピングツールに対する誤解」をとき、多くの方々にO/Rマッピングツールの目的やメリットを正しく理解してもらうことです。
そして、もしO/Rマッピングツールに関する議論や批判をするならば、あくまでこうした前提を共通認識として持ってもらった上で議論してほしいと考えています。


以上、長々としたシリーズになってしまいましたが、こうしたブログが少しでもみなさんのお役に立てば幸いです。