Was ist Ruhezustand? Fundamental für die Implementierung von Hibernate Core

Veröffentlicht: 2013-04-17

Java-Beispiel für den Ruhezustand

Hibernate ist ein Open-Source-Java-Persistenz-Framework-Projekt. Führen Sie leistungsstarkes objektrelationales Mapping durch und fragen Sie Datenbanken mit HQL und SQL ab.

Im Allgemeinen sind die weit verbreiteten Bibliotheken gut entworfen und implementiert, und es ist sehr interessant, von ihnen einige Best Practices für die Codierung zu lernen.

Werfen wir einen Blick in die Kernbibliothek von Hibernate und entdecken Sie einige ihrer Designschlüssel.

In diesem Beitrag wird Hibernate Core von JArchitect analysiert, um tief in sein Design und seine Implementierung einzudringen.

Paket nach Funktion

Package-by-feature verwendet Pakete, um den Funktionssatz widerzuspiegeln. Es platziert alle Elemente, die sich auf ein einzelnes Feature (und nur dieses Feature) beziehen, in einem einzigen Verzeichnis/Paket. Dies führt zu Paketen mit hoher Kohäsion und hoher Modularität und mit minimaler Kopplung zwischen Paketen. Gegenstände, die eng zusammenpassen, werden nebeneinander platziert.

Der Hibernate-Kern enthält viele Pakete, von denen jedes mit einer bestimmten Funktion hql, sql und anderen zusammenhängt.

Hibernate Core-Pakete - Crunchify.com

Kupplung

Eine geringe Kopplung ist wünschenswert, da eine Änderung in einem Bereich einer Anwendung weniger Änderungen in der gesamten Anwendung erfordert. Auf lange Sicht könnte dies viel Zeit, Aufwand und Kosten verringern, die mit dem Ändern und Hinzufügen neuer Funktionen zu einer Anwendung verbunden sind.

Hier sind drei Hauptvorteile, die sich aus der Verwendung von Schnittstellen ergeben:

  • Eine Schnittstelle bietet eine Möglichkeit, einen Vertrag zu definieren, der die Wiederverwendung fördert. Wenn ein Objekt eine Schnittstelle implementiert, muss dieses Objekt einem Standard entsprechen. Ein Objekt, das ein anderes Objekt verwendet, wird Verbraucher genannt. Eine Schnittstelle ist ein Vertrag zwischen einem Objekt und seinem Verbraucher.
  • Eine Schnittstelle bietet auch eine Abstraktionsebene, die Programme leichter verständlich macht. Schnittstellen ermöglichen es Entwicklern, über das allgemeine Verhalten von Code zu sprechen, ohne sich mit vielen detaillierten Einzelheiten befassen zu müssen.
  • Eine Schnittstelle erzwingt eine geringe Kopplung zwischen Komponenten, was es einfach macht, den Schnittstellenkonsumenten vor Implementierungsänderungen in den Klassen zu schützen, die die Schnittstellen implementieren.

Lassen Sie uns nach allen von Hibernate Core definierten Schnittstellen suchen, dafür verwenden wir CQLinq , um die Codebasis abzufragen.

jboss11- Crunchify.com

Wenn unser primäres Ziel darin besteht, eine niedrige Kopplung zu erzwingen, gibt es einen häufigen Fehler bei der Verwendung von Schnittstellen, der den Nutzen ihrer Verwendung zunichte machen könnte. Es ist die Verwendung der konkreten Klassen anstelle von Schnittstellen, und um dieses Problem besser zu erklären, nehmen wir das folgende Beispiel:

Die Klasse A implementiert das Interface IA, das die Methode compute() enthält, die Consumer-Klasse C ist so implementiert

Die Klasse C verweist nicht auf die Schnittstelle IA, sondern auf die Klasse A. In diesem Fall verlieren wir den Vorteil der geringen Kopplung, und diese Implementierung hat zwei große Nachteile:

  • Wenn wir uns entscheiden, eine andere Implementierung von IA zu verwenden, müssen wir den Code der C-Klasse ändern.
  • Wenn einige Methoden zu A hinzugefügt werden, die in IA nicht vorhanden sind, und C sie verwendet, verlieren wir auch den Vertragsvorteil der Verwendung von Schnittstellen.

C# hat die Fähigkeit zur expliziten Schnittstellenimplementierung in die Sprache eingeführt, um sicherzustellen, dass eine Methode aus der IA niemals von einer Referenz auf konkrete Klassen aufgerufen wird, sondern nur von einer Referenz auf die Schnittstelle. Diese Technik ist sehr nützlich, um Entwickler davor zu schützen, die Vorteile der Verwendung von Schnittstellen zu verlieren.

Mit JArchitect können wir diese Art von Fehlern mit CQLinq , die Idee ist, nach allen Methoden aus konkreten Klassen zu suchen, die direkt von anderen Methoden verwendet werden.

Details zu hibernate2 - Crunchify.com

Von diesem Problem ist beispielsweise die Methode getEntityPersister von SessionFactoryImpl betroffen, die die Schnittstelle SessionFactoryImplementor implementiert.

Lassen Sie uns nach Methoden suchen, die SessionFactoryImpl.getEntityPersister direkt aufrufen.

Hibernate-Tutorial - Crunchify.com

Methoden wie SessionImpl.instantiate rufen getEntityPersister direkt auf, anstatt die Schnittstelle zu übergeben, was den Vorteil der Verwendung von Schnittstellen zunichte macht. Glücklicherweise enthält Hibernate Core nicht viele Methoden, die dieses Problem haben.

Kopplung mit externen Gläsern

Wenn externe Bibliotheken verwendet werden, ist es besser zu prüfen, ob wir eine Bibliothek eines Drittanbieters leicht durch eine andere ändern können, ohne die gesamte Anwendung zu beeinträchtigen. Es gibt viele Gründe, die uns dazu ermutigen können, eine Bibliothek eines Drittanbieters zu ändern.

Die andere Bibliothek könnte:

  • Mehr Funktionen haben
  • Stärker
  • Sicherer

Nehmen wir das Beispiel von antlr lib , das verwendet wurde, um die hql-Abfragen zu analysieren, und stellen Sie sich vor, dass ein anderer Parser erstellt wurde, der leistungsfähiger als antlr ist. Können wir antlr einfach durch den neuen Parser ändern?

Um diese Frage zu beantworten, suchen wir, welche Methoden von Hibernate sie direkt verwenden:

Details zum Ruhezustand - Crunchify

Und welche haben es indirekt verwendet:

Hibernate Funda - Java-Tutorials - Crunchify

Viele Methoden verwenden antlr direkt, was den Hibernate-Kern stark damit gekoppelt macht, und das Ändern von antlr durch einen anderen ist keine leichte Aufgabe. Diese Tatsache bedeutet nicht, dass wir ein Problem mit dem Hibernate-Design haben, aber wir müssen vorsichtig sein, wenn wir eine Bibliothek eines Drittanbieters verwenden, und prüfen, ob eine Bibliothek eines Drittanbieters niedrig mit der Anwendung gekoppelt sein muss oder nicht.

Zusammenhalt

Das Single-Responsibility-Prinzip besagt, dass eine Klasse einen und nur einen Grund haben sollte, sich zu ändern. Man sagt, dass eine solche Klasse kohäsiv ist. Ein hoher LCOM Wert weist im Allgemeinen auf eine schlecht kohäsive Klasse hin. Es gibt mehrere LCOM-Metriken. Das LCOM nimmt seine Werte im Bereich [0–1] an. Der LCOMHS (HS steht für Henderson-Sellers) nimmt seine Werte im Bereich [0–2] an. Beachten Sie, dass die LCOMHS-Metrik oft als effizienter angesehen wird, um nicht kohäsive Typen zu erkennen.

Ein LCOMHS-Wert über 1 sollte als alarmierend angesehen werden.

Im Allgemeinen sind die Klassen, die viele Methoden und Felder haben, stärker von der Kohäsion betroffen.

Lassen Sie uns nach Typen suchen, die viele Methoden und Felder haben.

hibernate6 - Knirschen

Nur wenige Typen sind von dieser Abfrage betroffen, und für alle ist der LCOMHS kleiner als 1.

Anmerkungen verwenden

Die annotationsbasierte Entwicklung entlastet Java-Entwickler von der umständlichen Konfiguration. Und geben Sie uns eine leistungsstarke Funktion, um den Quellcode vom Boilerplate-Code zu befreien. Es ist auch weniger wahrscheinlich, dass der resultierende Code Fehler enthält.

Lassen Sie uns nach allen Anmerkungen suchen, die von Hibernate Core definiert wurden.

hibernate7 - Crunchify.com

Viele Anmerkungen sind definiert, was den Ruhezustand für Entwickler einfach zu verwenden macht, und die Kopfschmerzen von Konfigurationsdateien werden vermieden.

Fazit

Hibernate Core ist ein gutes Beispiel für Open-Source-Projekte, von denen man lernen kann. Zögern Sie nicht, einen Blick hineinzuwerfen.