Java >> Java Tutorial >  >> Java

Was ich diese Woche gelernt habe (Woche 42/2013)

Jede Woche schreibe ich einen Blogbeitrag, der beschreibt, was ich in dieser Woche gelernt habe. Ich schreibe diese Blogbeiträge aus zwei Gründen.

Zuerst , ich möchte meine persönliche Entwicklung im Auge behalten, und das Schreiben regelmäßiger Blogbeiträge ist eine großartige Möglichkeit, dies zu tun.

Zweiter , ich möchte meine Erkenntnisse mit Ihnen teilen. Ich hoffe, dass Sie einige davon in Ihrer täglichen Arbeit verwenden können.

Fangen wir an und finden heraus, was ich in Woche 42 gelernt habe.

Was ich in Woche 42 gelernt habe

Zuerst , Eine geringe Codeabdeckung ist ein guter Indikator für technische Schulden.

Meine Erfahrung hat mich gelehrt, dass oft, wenn ein Softwareprojekt ernsthafte technische Probleme hat, es auch eine geringe Codeabdeckung hat. Die offensichtlichsten Probleme, die durch geringe Codeabdeckung verursacht werden, sind:

  1. Sie können nicht einfach überprüfen, ob Ihr Code funktioniert.
  2. Sie können nicht einfach sicherstellen, dass Ihre Änderungen nichts beschädigen.

Natürlich könnten Sie argumentieren, dass Unit-Tests nur zum Testen einzelner Komponenten verwendet werden können, und Sie hätten Recht. Das bringt uns zu einem weniger bekannten Vorteil von Komponententests:

Unit-Testing ist eigentlich ein Design-Tool!

Das Schreiben von Unit-Tests hilft dabei, beschissenen Code zu identifizieren, selbst wenn Sie TDD nicht verwenden, solange Sie sich an diese Regel erinnern:

Beschissener Code ist schwer zu testen!

Mit anderen Worten, wenn sich das Schreiben von Tests für Ihren Code schwer anfühlt, ist dies ein Zeichen dafür, dass Ihr Code Mist ist. Schauen Sie sich Ihren Code genau an und verbessern Sie ihn. Nachdem Sie Ihren Code bereinigt haben, sollten Sie keine Probleme mehr haben, Tests dafür zu schreiben.

Ein Wort der Warnung:Auch wenn eine niedrige Codeabdeckung bedeutet, dass Sie wahrscheinlich in Schwierigkeiten stecken, bedeutet eine hohe Codeabdeckung nicht unbedingt, dass Ihre Anwendung schuldenfrei ist. Beispielsweise ist es möglich, dass Sie in Ihren Tests technische Schulden haben!

Zweiter , Wir können das Gesetz von Brook nicht besiegen.

Das Brook's Law ist ein Softwareentwicklungsprinzip, das Folgendes besagt:

"Wenn man einem späten Softwareprojekt Arbeitskräfte hinzufügt, wird es später."

Wenn unser Projekt in Verzug ist (oder in Schwierigkeiten gerät) und wir es beschleunigen müssen, ist der richtige Weg, dies zu tun, zu versuchen, die Produktivität unserer bestehenden Teammitglieder zu steigern. Wir müssen alle unnötigen Ablenkungen beseitigen, damit sich diese Leute darauf konzentrieren können, das Projekt wieder auf Kurs zu bringen.

Auf der anderen Seite leben wir nicht in einer idealen Welt und manchmal ist es notwendig, ein Projekt mit Arbeitskräften zu besetzen, selbst wenn wir wissen, dass es uns schaden wird.

In diesem Fall müssen wir den Schaden minimieren .

Eine Möglichkeit, dies zu tun, besteht darin, unseren neuen Teammitgliedern einfache Aufgaben zu übertragen, die keine Domänenkenntnisse erfordern. Dies kann für die neuen Teammitglieder etwas demotivierend sein, aber es bedeutet, dass die alten Teammitglieder mehr Zeit mit der Arbeit an den Aufgaben verbringen können, die Domänenkenntnisse erfordern.

Wenn dies nicht in Frage kommt, besteht eine Möglichkeit darin, jedem neuen Teammitglied ein Programmierpaar zuzuweisen und jedem Paar Aufgaben zuzuweisen. Auf diese Weise können die alten Teammitglieder ihr Domänenwissen auf die neuen übertragen. Dies ist auf kurze Sicht wahrscheinlich schmerzhaft, aber auf lange Sicht wird es dem Projekt helfen.

Wenn wir das auch nicht schaffen, sind wir am Arsch und sollten uns darauf vorbereiten, das Schiff zu verlassen, bevor es auf den Eisberg trifft.

Dritter , Lassen Sie Ihre Datenbank ihre Arbeit erledigen.

Ich habe festgestellt, dass viele Entwickler denken, dass der größte Vorteil von ORMs darin besteht, dass Entwickler eine Entität aus der Datenbank abrufen und ihre Beziehungen träge laden können, wenn sie sie brauchen. Mit anderen Worten, diese Entwickler führen Tabellenverknüpfungen in ihrem Code aus.

Aus meiner Sicht haben ORMs drei große Vorteile:

  1. Ich muss keinen Boilerplate-Code schreiben, der Ergebnismengen in Objekte umwandelt.
  2. Ich muss keine Datenbankabfragen erstellen, die Daten in die Datenbank einfügen.
  3. Wenn ich Änderungen an persistenten Objekten innerhalb einer Lese-Schreib-Transaktion vornehme, muss ich diese Änderungen nicht manuell in der Datenbank aktualisieren.

Ich möchte Join-Operationen in der Datenbank ausführen, weil

  1. Das ist die Verantwortung einer relationalen Datenbank, und sie sind gut darin.
  2. Dies hilft, das berüchtigte n+1-Auswahlproblem zu vermeiden.

Außerdem bin ich mir der Tatsache sehr wohl bewusst, dass einige Entwickler denken, dass eine Join-Operation langsam ist, aber in Wirklichkeit ist die Leistung von Join-Operationen sehr gut, wenn sie auf die richtige Art und Weise durchgeführt werden.

Wenn Sie die relationale Datenbank nur als Key-Value-Store nutzen möchten, sollten Sie sich ernsthaft diese Frage stellen:

Brauche ich wirklich eine relationale Datenbank oder sollte ich ein *keuch* verwenden echter Schlüsselwertspeicher?

Vierter , Erstellen Sie eine Datenbankabfrage pro Anwendungsfall.

Mir ist aufgefallen, dass Entwickler (mich eingeschlossen) dazu neigen, so viel Code wie möglich wiederzuverwenden. Das ist eine gute Sache, aber die Wiederverwendung von Datenbankabfragen ist eine schlechte Idee, da Sie die Leistung nicht für einen bestimmten Anwendungsfall optimieren können. Das bedeutet, dass Sie eine Abfrage erstellen müssen, deren Leistung für alle unterstützten Anwendungsfälle gut genug ist.

Mit anderen Worten, die Leistung Ihrer Anwendung ist nicht so gut, wie sie sein könnte.

Davon abgesehen, wenn dieselbe Datenbankabfrage wirklich mehr als einen Anwendungsfall unterstützen kann (dieselbe select-Klausel und dieselbe where-Klausel können verwendet werden), ist es in Ordnung, diese Abfrage für alle Anwendungsfälle zu verwenden. Denken Sie jedoch daran, dass Sie bei einer Änderung der Situation eine neue Datenbankabfrage(n) erstellen müssen, anstatt die vorhandene zu ändern.

Fünfter , Wenn Sie nur Informationen anzeigen, geben Sie Datenübertragungsobjekte anstelle von Entitäten zurück.

Wenn Sie Informationen auf der Benutzeroberfläche anzeigen müssen, stehen Sie möglicherweise vor einer der folgenden Situationen:

  1. Du brauchst nicht alle Felder einer Entität.
  2. Sie müssen Informationen aus mehreren Entitäten kombinieren, erhalten aber nur wenige Felder pro Entität.

Wenn Sie mit einer dieser Situationen konfrontiert sind, stellen Sie sich zwei Fragen:

  1. Wenn ich nur wenige Felder benötige, ist es sinnvoll, alle Felder der Entität zu erhalten?
  2. Wenn ich Informationen aus mehreren Entitäten kombinieren muss, aber nur wenige Felder pro Entität benötige, ist es dann sinnvoll, alle Felder aller Entitäten zu erhalten?

Seien wir hier ehrlich. Oft ist Faulheit der einzige Grund, warum wir Entitäten abfragen. Wir sind zu faul, über diese Fragen nachzudenken, weil wir der Meinung sind, dass der Aufwand für die Abfrage von Entitäten keine Rolle spielt. Nun, wie oft testen wir, wie hoch der Overhead wirklich ist?

Genau!

Früher war ich ein großer Fan von Abfragen von Entitäten, aber meine jüngsten Erfahrungen haben mir gezeigt, dass es nur dann Sinn macht, wenn ich etwas aktualisieren oder löschen möchte. Wenn ich nur Informationen lesen möchte, ist es oft am schnellsten, DTOs anstelle von Entitäten zurückzugeben.

Dies erfordert etwas mehr Arbeit, aber wir können die Option, die uns die beste Leistung liefert, nicht einfach ignorieren, nur weil wir faul sind. Richtig?

Übrigens, hier sind einige Vorschläge, wie Sie DTOs anstelle von Entitäten abfragen können:

  1. Wenn Sie Hibernate verwenden, können Sie die AliasToBeanResultTransformer-Klasse verwenden.
  2. Wenn Sie SQL mögen, werfen Sie einen Blick auf die Bibliothek namens jOOQ. Es unterstützt mehrere Möglichkeiten zum Abrufen von Daten aus der Datenbank und bietet eine einfache Möglichkeit, Ihre Abfrageergebnisse in POJOs abzubilden. Wenn Ihnen die Mapping-Fähigkeiten von jOOQ nicht gut genug sind, können Sie jOOQ auch mit ModelMapper integrieren.

Was hast du diese Woche gelernt?

Teilen Sie Ihre Lernerfahrungen oder andere Kommentare im Kommentarbereich.


Java-Tag