Hibernateとは何ですか? Hibernateコア実装の基本

公開: 2013-04-17

JavaHibernateの例

HibernateはオープンソースのJava永続性フレームワークプロジェクトです。 HQLとSQLを使用して、強力なオブジェクトリレーショナルマッピングとクエリデータベースを実行します。

一般に、広く使用されているライブラリは適切に設計および実装されており、それらからコーディングのベストプラクティスを学ぶことは非常に興味深いことです。

Hibernateコアライブラリの内部を見て、そのデザインキーのいくつかを見つけましょう。

この投稿では、Hibernate CoreがJArchitectによって分析され、その設計と実装の詳細が示されています。

機能別パッケージ

Package-by-featureは、パッケージを使用して機能セットを反映します。 単一の機能(およびその機能のみ)に関連するすべてのアイテムを単一のディレクトリ/パッケージに配置します。 これにより、パッケージ間の凝集度とモジュール性が高く、パッケージ間の結合が最小限に抑えられます。 密接に連携するアイテムは、隣り合って配置されます。

Hibernateコアには多くのパッケージが含まれており、各パッケージは特定の機能hql、sqlなどに関連しています。

Hibernateコアパッケージ-Crunchify.com

カップリング

アプリケーションの1つの領域での変更は、アプリケーション全体で必要な変更が少なくなるため、低結合が望ましいです。 長期的には、これにより、アプリケーションの変更や新機能の追加に関連する多くの時間、労力、およびコストを削減できます。

インターフェイスを使用することで得られる主なメリットは次の3つです。

  • インターフェイスは、再利用を促進するコントラクトを定義する方法を提供します。 オブジェクトがインターフェースを実装する場合、そのオブジェクトは標準に準拠する必要があります。 別のオブジェクトを使用するオブジェクトは、コンシューマーと呼ばれます。 インターフェイスは、オブジェクトとそのコンシューマーの間のコントラクトです。
  • インターフェイスは、プログラムを理解しやすくする抽象化のレベルも提供します。 インターフェイスを使用すると、開発者は、多くの詳細な詳細に触れることなく、コードの動作の一般的な方法について話し始めることができます。
  • インターフェイスは、コンポーネント間の低結合を強制します。これにより、インターフェイスを実装するクラスの実装変更からインターフェイスコンシューマを簡単に保護できます。

Hibernate Coreによって定義されたすべてのインターフェースを検索してみましょう。そのために、 CQLinqを使用してコードベースをクエリします。

jboss11- Crunchify.com

私たちの主な目標が低結合を強制することである場合、それらを使用するユーティリティを殺す可能性のあるインターフェースを使用するときによくある間違いがあります。 これは、インターフェースの代わりに具象クラスを使用することです。この問題をよりよく説明するために、次の例を見てみましょう。

クラスAはcalculate()メソッドを含むインターフェイスIAを実装し、コンシューマークラスCはそのように実装されます

クラスCは、インターフェイスIAを参照する代わりに、クラスAを参照します。この場合、結合度が低いという利点が失われます。この実装には、次の2つの大きな欠点があります。

  • IAの別の実装を使用することにした場合は、Cクラスのコードを変更する必要があります。
  • IAに存在しないAにいくつかのメソッドが追加され、Cがそれらを使用すると、インターフェイスを使用するという契約上のメリットも失われます。

C#は、言語に明示的なインターフェイス実装機能を導入して、IAのメソッドが具象クラスへの参照から呼び出されることはなく、インターフェイスへの参照からのみ呼び出されるようにしました。 この手法は、開発者がインターフェイスを使用するメリットを失うのを防ぐのに非常に役立ちます。

CQLinqでは、CQLinqを使用してこの種の間違いをチェックできます。アイデアは、他のメソッドによって直接使用される具象クラスからすべてのメソッドを検索することです。

hibernate2の詳細-Crunchify.com

たとえば、SessionFactoryImplementorインターフェイスを実装するSessionFactoryImplのメソッドgetEntityPersisterは、この問題に関係しています。

SessionFactoryImpl.getEntityPersisterを直接呼び出すメソッドを検索してみましょう。

hibernateチュートリアル-Crunchify.com

SessionImpl.instantiateのようなメソッドは、インターフェイスを渡すのではなく、直接getEntityPersisterを呼び出します。これは、インターフェイスを使用する利点を損なうものです。 幸い、Hibernateコアには、この問題を抱えている多くのメソッドが含まれていません。

外部jarとの結合

外部ライブラリを使用する場合は、アプリケーション全体に影響を与えることなく、サードパーティのライブラリを別のライブラリに簡単に変更できるかどうかを確認することをお勧めします。サードパーティのライブラリを変更するように促す理由はたくさんあります。

他のlibは:

  • より多くの機能があります
  • 更に力強い
  • より安全に

hqlクエリを解析するために使用されたantlr libの例を見て、antlrよりも強力な別のパーサーが作成されたと想像してみましょう。新しいパーサーでantlrを簡単に変更できますか?

この質問に答えるために、休止状態のどのメソッドが直接それを使用するかを検索しましょう。

ハイバネートの詳細-Crunchify

そして、それを間接的に使用したのはどれですか?

HibernateFunda-Javaチュートリアル-Crunchify

多くの方法では、antlrを直接使用するため、Hibernateコアが高度に結合されており、antlrを別のコアに変更するのは簡単な作業ではありません。 この事実は、休止状態の設計に問題があることを意味するわけではありませんが、サードパーティのlibを使用する場合は注意が必要であり、サードパーティのlibがアプリケーションと低結合である必要があるかどうかを十分に確認する必要があります。

凝集

単一責任の原則は、クラスには変更する理由が1つだけあるべきであると述べています。 そのようなクラスはまとまりがあると言われています。 LCOM値が高い場合は、通常、まとまりのないクラスを特定します。 いくつかのLCOMメトリックがあります。 LCOMは、[0-1]の範囲の値を取ります。 LCOMHS(HSはHenderson-Sellersの略)は、[0-2]の範囲の値を取ります。 LCOMHSメトリックは、非凝集型を検出するのにより効率的であると見なされることが多いことに注意してください。

1より大きいLCOMHS値は、警告と見なす必要があります。

一般に、凝集度に関心のあるクラスは、多くのメソッドとフィールドを持つクラスです。

多くのメソッドとフィールドを持つタイプを検索してみましょう。

hibernate6-Crunchify

このクエリに関係するタイプはごくわずかであり、それらすべてについて、LCOMHSは1未満です。

注釈の使用

アノテーションベースの開発は、Java開発者を面倒な設定の苦痛から解放します。 そして、ボイラープレートコードからソースコードを解放するための強力な機能を提供してください。 結果のコードにもバグが含まれる可能性は低くなります。

hibernateコアによって定義されたすべてのアノテーションを検索してみましょう。

hibernate7-Crunchify.com

多くのアノテーションが定義されており、開発者がHibernateを使いやすくし、構成ファイルの問題を回避できます。

結論

Hibernate Coreは、学ぶべきオープンソースプロジェクトの良い例です。遠慮なくその中を見てください。