Java - statische Factory-Methode und Switch-Anweisungen

7

Ich habe es mit einer Menge von Nachrichtenobjekten zu tun, von denen jedes eine eindeutige Kennung hat, die ihnen entspricht. Jede Nachricht kann entweder aus einer Map oder aus einem ByteBuffer erstellt werden (die Nachrichten sind binär, aber wir wissen, wie man zu und von einer binären Repräsentation überträgt).

Die aktuelle Implementierung zum Erstellen dieser Nachrichten ist grob wie folgt:

%Vor%

Nun, Josh Blochs effektives Java spricht über Punkt 1: Betrachte statische Fabrikmethoden anstelle von Konstruktoren und dies scheint ein Ort zu sein, an dem dieses Muster nützlich ist (Clients greifen nicht direkt auf die Konstruktoren der Nachrichtenuntertypen zu; stattdessen durchlaufen sie diese Methode). Aber ich mag es nicht, dass wir daran denken müssen, zwei Switch-Statements auf dem neuesten Stand zu halten (verstößt gegen das Prinzip DRY ) .

Ich würde jede Einsicht in den besten Weg schätzen, dies zu erreichen; Objekte werden nicht zwischengespeichert (jeder Aufruf von fromMap oder fromByteBuffer gibt ein neues Objekt zurück), wodurch einige Vorteile einer solchen statischen Factory-Methode zunichte gemacht werden. Etwas an diesem Code erscheint mir falsch, daher würde ich gerne die Gedanken der Community darüber hören, ob dies ein gültiger Weg ist, um neue Objekte zu konstruieren, oder ob nicht, was eine bessere Lösung wäre.

    
I82Much 11.01.2010, 16:54
quelle

9 Antworten

12

Vielleicht könnten Sie eine Schnittstelle MessageFactory und Implementierungen davon erstellen:

%Vor%

Als nächstes folgt eine Methode getFactoryFromId in derselben Klasse wie die obigen Methoden:

%Vor%

Stattdessen ist es jedoch besser, eine Hashmap zu erstellen, die die IDs und die Factories enthält, sodass Sie nicht jedes Mal ein neues Factory-Objekt erstellen müssen, wenn Sie eine Nachricht erstellen. Siehe auch den Kommentar .

und Ihre Methoden:

%Vor%

Auf diese Weise verwenden Sie das Factory-Muster, und es ist nicht notwendig, zweimal dieselbe switch-Anweisung zu verwenden.

(hat das nicht getestet, also möglicherweise einige Kompilierfehler / Tippfehler)

    
Fortega 11.01.2010, 17:06
quelle
3
  

tem 1: Berücksichtigen Sie statische Factory-Methoden anstelle von Konstruktoren

Sie tun dies bereits, indem Sie den Konstruktor hinter dieser Factory-Methode verbergen, sodass Sie hier keine weitere Factory-Methode hinzufügen müssen.

So können Sie es mit einer Factory-Oberfläche und einer Karte machen. (Grundsätzlich, was alle schon sagen, aber mit dem Unterschied, dass Sie die Fabriken mit inneren Klassen inline)

%Vor%

Und deine Aufrufe werden zu:

%Vor%

Da die für den Switch verwendete UUID als Schlüssel für die Fabriken verwendet wird.

    
OscarRyz 11.01.2010 18:03
quelle
3

Wenn Ihre Objekte eine Schnittstelle implementieren, deklarieren Sie Factory-Methoden wie:

%Vor%

In einer statischen geschachtelten Klasse kann Ihre Factory ein Map erstellen, das Factory-Objekte enthält, die von der UUID indiziert sind:

%Vor%

und ersetzen Sie Ihre Schalter durch Kartensuche:

%Vor%

Dies kann leicht erweitert werden, um andere Konstruktionsmethoden zu unterstützen.

    
rsp 11.01.2010 17:18
quelle
1

Gibt es eine Möglichkeit, den ByteBuffer in eine Map oder etwas anderes umzuwandeln? Es wäre nett, wenn Sie die Eingabe in eine normalisierte Form konvertieren und einen eindeutigen Schalter anwenden.

Wenn Sie eine Nachricht erhalten und sie mit bestimmten Werten formatieren (wie "Die Tabelle: tabellenname hat keine Spalte namens: colName"), können Sie den ByteBuffer in eine Map konvertieren und die erste Methode aufrufen . Wenn Sie eine neue msgId benötigen, erweitern Sie nur die Methode fromMap.

Es ist etwas wie das Teilen des gemeinsamen Teils.

    
helios 11.01.2010 17:15
quelle
1

Ich empfehle einen Aufzählungstyp mit abstrakten Methoden, wie das folgende Beispiel:

%Vor%

Auf diese Weise können Sie das in Ihren bestehenden statischen Methoden einfach tun ...

%Vor%

Dieser Ansatz erspart Ihrer statischen Methode das Wissen über die von Ihnen unterstützten MessageTypes und deren Erstellung. Sie können Nachrichten hinzufügen, ändern oder entfernen, ohne die statischen Methoden zu refaktorieren.

    
Drew Wills 11.01.2010 17:20
quelle
0

Sie könnten das Muster AbstractFactory verwenden, in dem Sie für jeden Nachrichtentyp eine Factory-Klasse haben, die die Nachricht entweder per Puffer oder Map zurückgibt. Sie erstellen dann eine Methode, die Ihnen das entsprechende Factory-Objekt zurückgibt. Aus der zurückgegebenen Factory erstellen Sie dann die Nachricht.

    
bertolami 11.01.2010 17:10
quelle
0

Sie können Message so ändern, dass es zwei Initialisierungsmethoden hat, eine für Map und eine für ByteBuffer (anstelle der beiden Contructor-Versionen). Dann gibt Ihre Factory-Methode die konstruierte (aber nicht initialisierte) Nachricht zurück, dann rufen Sie initialize mit dem Map oder ByteBuffer für das zurückgegebene Objekt auf.

Sie haben jetzt eine Fabrikmethode wie folgt: -

%Vor%

und dann werden die öffentlichen Factory-Methoden: -

%Vor%

und

%Vor%     
tinyd 11.01.2010 17:40
quelle
0

Sie sollten Ihr Objekt FirstMessage abstrahieren:

%Vor%

Speichern Sie sie dann in Ihrer Fabrik (im Gegensatz zu einem Schalter):

%Vor%

In Ihrer Fabrikmethode:

%Vor%

Das ist sowieso nur eine Idee, Sie müßten einige Überlegungen machen (den Konstruktor holen), um die Felder zu übergeben.

    
Droo 11.01.2010 17:33
quelle
0

Über die Lösung, die die Aufzählung als Strategie verwendet (Hinzufügen von Strategie-Methoden zu einer Aufzählung), sagt die Cheet-Sheet-App mit cleanem Code, dass dies ein Instandhaltungsmörder ist Obwohl ich nicht weiß, warum ich das mit Ihnen teilen möchte.

    
Arno Noordover 05.04.2013 21:06
quelle

Tags und Links