Java >> Java Tutorial >  >> Java

Drei Gründe, warum ich das Builder-Muster mag

Es gibt drei Möglichkeiten, neue Objekte in der Programmiersprache Java zu erstellen:

  1. Das (Anti-)Muster des teleskopierenden Konstruktors
  2. Das Javabeans-Muster
  3. Das Builder-Muster

Ich bevorzuge das Builder-Muster gegenüber den beiden anderen Methoden.

Warum?

Joshua Bloch beschrieb das Builder-Muster und die Vorteile seiner Verwendung in Effective Java. Er hat hervorragende Arbeit geleistet und ich werde diese Vorteile in diesem Blogbeitrag nicht wiederholen.

Stattdessen werde ich drei weitere Gründe beschreiben, warum ich das Builder-Muster dem teleskopischen Konstruktor-Muster und dem Javabeans-Muster vorziehe.

1. Es hilft Ihnen, ein besseres Design durchzusetzen

Die Verwendung des teleskopierenden Konstruktormusters oder des Javabeans-Musters bedeutet, dass die Eigenschaften des erstellten Objekts erstellt werden müssen, bevor das eigentliche Objekt erstellt wird.

Dies kann ein Problem sein oder auch nicht.

Wenn die Eigenschaften des erstellten Objekts mithilfe eines externen Dienstes abgerufen werden, ist dies kein Problem. Wenn die Eigenschaften jedoch in der Methode erstellt werden, die das "Ziel"-Objekt erstellt, ist dies ein Problem.

Im letzteren Szenario ist der Lebenszyklus der erstellten Objekte oft an den Lebenszyklus des "Ziel"-Objekts gebunden.

Wenn dies der Fall ist, kann Ihnen das Builder-Muster dabei helfen, das als Aggregat bezeichnete DDD-Muster (Domain Driven Design) zu verwenden. Martin Fowler spezifiziert das Gesamtmuster wie folgt:

Ein DDD-Aggregat ist ein Cluster von Domänenobjekten, die als einzelne Einheit behandelt werden können. Ein Beispiel könnte eine Bestellung und ihre Einzelposten sein, diese sind separate Objekte, aber es ist sinnvoll, die Bestellung (zusammen mit ihren Einzelposten) als ein einzelnes Aggregat zu behandeln.

Das Builder-Muster kann Ihnen helfen, Ihren Code so zu gestalten, dass Ihr Domänenmodell in Aggregate unterteilt wird. Das bedeutet, dass alle zum Aggregat gehörenden Objekte vom Aggregat-Root-Objekt (Order) erzeugt werden und nur über das Aggregat-Root-Objekt zugreifbar sind.

Damit rückt die Konstruktionsbeziehung zur Logik an den Ort, wo sie hingehört.

2. Es regt zum Nachdenken an

Das Schreiben von Code auf herkömmliche Weise ist einfach, da Sie nicht nachdenken müssen. Alles, was Sie tun müssen, ist den Code zu schreiben, der Informationen von einem Ort zum anderen kopiert. Es kann einige Zeit dauern, dies zu tun, aber es ist kein Problem für Sie, da Sie sich in Ihrer Komfortzone befinden.

Vielleicht möchten Sie einfach Code knacken, ohne darüber nachzudenken, was Sie tun.

Ich bin nicht so (und du solltest es auch nicht sein).

Das Builder-Muster zwingt Sie, über Ihre Objekte nachzudenken. Genauer gesagt zwingt es Sie, über die folgenden Dinge nachzudenken:

  • Sie müssen die obligatorischen und optionalen Eigenschaften eines Objekts herausfinden.
  • Sie müssen die Eigenschaften identifizieren, deren Lebenszyklus an den Lebenszyklus des erstellten Objekts gebunden ist, und den Builder so gestalten, dass er dies betont.
  • Sie müssen entscheiden, welche Eigenschaften nicht aktualisiert werden können, nachdem das Objekt erstellt wurde (und diese Eigenschaften als endgültig markieren).
  • Sie müssen entscheiden, welche Eigenschaften aktualisiert werden können, und den besten Weg finden, sie zu aktualisieren.

Wenn Sie Antworten auf diese Fragen finden, können Sie besseren Code schreiben. Ich kann garantieren, dass Ihr Code viel besser aussehen wird als der auf Autopilot geschriebene Code, wenn Sie sich die Zeit nehmen, die Antworten auf diese Fragen zu finden.

3. Es hilft Ihnen, domänenspezifische Sprachen zu erstellen

Wenn Sie neue Objekte erstellen, indem Sie das teleskopierende Konstruktormuster oder das Javabeans-Muster verwenden, ist es schwierig, Ihrem Code eine geschäftliche Bedeutung hinzuzufügen. Sie können versuchen, die Situation zu verbessern, indem Sie diese Prinzipien befolgen:

  • Die einzige Möglichkeit, Konstruktorargumenten eine geschäftliche Bedeutung hinzuzufügen, besteht darin, die Argumente richtig zu benennen. Dies ist schwierig und selbst wenn Sie es richtig machen, sind die Ergebnisse nicht optimal.
  • Wenn Sie Setter verwenden, können Sie die Setter-Methoden natürlich so benennen, dass sie eine geschäftliche Bedeutung haben. Aber wie oft haben Sie Setter-Methoden gesehen, die nach diesem Prinzip benannt sind?

99 von 100 der erstellten Objekte sind nur Objekte ohne Bedeutung. Sie halten Daten. Das ist alles.

Wenn Sie das Builder-Muster verwenden, können Sie eine domänenspezifische Sprache (DSL) zum Erstellen neuer Objekte erstellen, indem Sie die Methoden Ihrer Builder-Klasse benennen. Dies hilft Ihnen, dem Code, der neue Objekte erstellt, eine geschäftliche Bedeutung hinzuzufügen.

Dies wirft eine Frage auf:Wie kann ich die Eigenschaften meiner Objekte aktualisieren?

Sie können natürlich langweilig sein und Setter-Methoden verwenden, um die einzelnen Eigenschaften Ihrer Objekte zu aktualisieren. Aber Sie können auch etwas ganz anderes machen.

Anstatt einzelne Eigenschaften zu aktualisieren, können Sie diese Eigenschaften in sinnvolle Gruppen gruppieren und die Werte dieser Eigenschaften in einer einzigen Methode aktualisieren. Wenn Sie diese Methode richtig benennen, können Sie eine DSL zum Aktualisieren der Informationen vorhandener Objekte erstellen.

Es ist keine Wunderwaffe

Blake Caldwell sagt, dass das Builder-Muster grundsätzlich eine weniger fehleranfällige Alternative für Konstruktoren ist. Ich stimme ihm zu.

Das erste, was Sie bemerken, wenn Sie anfangen, das Builder-Muster zu verwenden, ist, dass der Code, der neue Objekte erstellt, einfacher zu schreiben und zu lesen ist. Nach einiger Zeit bemerken Sie jedoch möglicherweise auch andere Vorteile. Ich weiß, dass ich es getan habe.

Es ist jedoch wichtig, dass Sie verstehen, dass das Builder-Muster keine Wunderwaffe ist .

Ich denke, dass niemand einer Best Practice folgen sollte, nur weil es eine Best Practice ist. Dies gilt auch für das Builder-Muster.

Wenn Ihr Objekt nur wenige Konstruktorargumente hat, macht es keinen Sinn, das Builder-Muster zu verwenden. Aufgrund der in diesem Blogpost (und in Effective Java) beschriebenen Vorteile sollten Sie dies jedoch sollten Ziehen Sie in Betracht, das Builder-Muster jedes Mal zu verwenden, wenn Sie neue Objekte erstellen müssen.


Java-Tag