Innere Klasse für jedes Mitglied von enum?

8

Ich bin mir nicht sicher, ob das, was ich will, möglich ist, aber ich versuche ein Enum zu schaffen, in dem jedes Mitglied seine eigene innere Klasse hat. Diese inneren Klassen haben alle den gleichen Namen Context , werden aber einzeln implementiert.

Idealerweise möchte ich, dass sie als solche verwendbar sind:

%Vor%

Offen für andere Möglichkeiten, dies zu implementieren. Aber im Grunde brauche ich eine umschaltbare Aufzählung, in der jedes Mitglied einen "Wert" hat (1,2,3 ...) und auch ein Mittel, diese Aufzählungen mit einer eindeutigen Klasse mit Konstruktor zu verbinden.

EDIT: Etwas Hintergrund. Dies soll zwischen zwei Diensten verwendet werden, die über JSON-HTTP-Anfragen kommunizieren. Die Anfragen enthalten einige Metadaten, von denen ein Feld eine Ganzzahl ist, die der Enumeration zugeordnet ist. Der Kontext ist ein POJO, ist jedoch für jeden ENUM_VALUE unterschiedlich. Im Wesentlichen wird der Kontext in JSON erstellt und serialisiert. Dieser json wird effektiv nur ein String-Feld namens context innerhalb der JSON-Anfrage der obersten Ebene sein. Auf dem empfangenden Dienst wird ein Schalter auf ENUM_VALUE geschaltet, in dem der Kontext entsprechend decodiert und dann an den entsprechenden Handler gesendet wird.

EDIT2: Diese Aufzählung wird zwischen den beiden Diensten geteilt.

EDIT3: Hier ist eine explizite Erklärung dessen, was ich versuche zu tun.

MyServiceRequest:

%Vor%

Generierungsanfrage:

%Vor%

Entschlüsselungsanforderung:

%Vor%     
thedarklord47 09.11.2017, 19:25
quelle

4 Antworten

9

Man könnte denken, Sie könnten stattdessen Ihre Enum implementieren Supplier<Context> . Jetzt müsste jedes Element eine get () -Methode deklarieren, um den individuellen Context-Untertyp zu erstellen.

%Vor%

was Ihren Client-Code viel einfacher machen würde:

%Vor%     
Sean Patrick Floyd 09.11.2017, 19:31
quelle
4

Warum eine innere Klasse verwenden?

Sie könnten einfach einen Feld -Kontext haben, der mit verschiedenen Werten für jede Enum-Konstante initialisiert wird. Wie:

%Vor%     
GhostCat 09.11.2017 19:31
quelle
1

Ich würde keine separate innere Klasse für jedes Enum empfehlen, nur eine separate Implementierung. Etwas wie unten wäre wahrscheinlich Ihre beste Vorgehensweise, dann müssen Sie kein switch statment verwenden. Weil Sie einfach getContext() für Ihre type Variable aufrufen können:

%Vor%     
Lino 09.11.2017 19:30
quelle
1

Das bedeutendste Problem mit dem, was Sie beschreiben, ist, dass Klassen, die auf einzelne Enum-Elemente beschränkt sind, keine Namen haben, die außerhalb dieses Elements auflösbar sind. Das macht es unmöglich, eine solche Klasse über den Operator new außerhalb des Aufzählungswerts zu instanziieren oder eine Methode außerhalb des Aufzählungswerts zu deklarieren, der diese Klasse als Argument oder Rückgabetyp hat.

Aber Sie können das weitgehend umgehen, indem Sie einen Schnittstellentyp für die zu implementierenden inneren Klassen deklarieren und eine Factory-Methode bereitstellen, die anstelle eines Konstruktors zum Abrufen von Instanzen dient. Zum Beispiel:

%Vor%

Ich denke jedoch, dass dies ein wenig zweifelhaft ist - vor allem mit Methoden, die für bestimmte Enum-Werte spezifisch sind und nicht zu diesen Enum-Werten gehören. Es gibt wahrscheinlich einen ganz anderen Ansatz, der Ihnen besser dienen würde, aber Sie haben das Problem zu allgemein beschrieben, als dass wir eine solche Alternative vorschlagen könnten.

Aktualisieren

Nachdem ich über Ihre Änderungen an der Frage und Ihren späteren Kommentaren nachgedacht habe, bin ich geneigt, bei meiner Einschätzung zu bleiben, dass das, was Sie vorschlagen, ein wenig zweifelhaft ist.

Machen Sie einen Schritt zurück und betrachten Sie das Problem aus einer breiteren Perspektive. Sie generieren, serialisieren (zu JSON), deserialisieren und konsumieren Anfragen verschiedener Typen (die derzeit durch einen ID-Code unterschieden werden, der darin enthalten ist). Es ist sinnvoll, jede Art von Anfrage mit einer Klasse zu versehen, die die entsprechenden Eigenschaften enthält, einschließlich derjenigen der verschiedenen Kontextdaten jedes Typs. Wenn es absichtliche Gemeinsamkeiten gibt, dann sollten diese vielleicht eine gemeinsame Schnittstelle implementieren, die sie beschreibt, oder sogar eine gemeinsame Basisklasse erweitern.

Damit ist die JSON-Serialisierung / Deserialisierung ein gelöstes (mehr als einmal) Problem. Wenn Sie das Rad nicht neu erfinden möchten, möchte ich Google GSON vorschlagen. Ich muss das mit einem Eingeständnis abklären, dass ich nicht viel persönliche Erfahrung mit GSON habe, aber es ist ziemlich populär, und du wirst hier viele Fragen (und Antworten) darüber sehen. Sie finden auch einige gute Online-Tutorials.

    
John Bollinger 09.11.2017 19:53
quelle

Tags und Links