Optionen zum Organisieren meines Projekts mit: JAX-RS API, ServiceLocator und Remote EJBs

8

Ich versuche herauszufinden, welche Optionen ich für die Architektur meines API-Projekts habe.

Ich möchte eine API mit JAX-RS Version 1.0 erstellen. Diese API verbraucht Remote EJBs (EJB 3.0) von einer größeren, alten und komplexen Anwendung. Ich benutze Java 6.

Bisher kann ich das machen und arbeite. Aber ich bin nicht mit der Lösung zufrieden. Siehe meine Paketdisposition. Meine Bedenken sind nach dem Code beschrieben:

%Vor%

Beispiel für com.organization.api.v1.rs.UserV1RS :

%Vor%

Beispiel für com.organization.api.v1.services.UserV1Service :

%Vor%

Beispiel für com.organization.api.services.UserService :

%Vor%

Einige Anforderungen meines Projekts:

  • Die API hat Versionen: v1, v2, etc.
  • Die verschiedenen API-Versionen desselben versionierten Dienstes können Code gemeinsam nutzen: UserV1Service und UserV2Service mit UserService .
  • Die verschiedenen API-Versionen verschiedener versionierter Dienste können den Code teilen: UserV1Service und OrderV2Service mit AnotherService .
  • Jede Version hat ihr eigenes View-Objekt ( UserV1VO und nicht UserVO ).

Was mich an dem obigen Code kaputt macht:

  1. Diese ServiceLocator Klasse ist für mich kein guter Ansatz. Diese Klasse verwendet Legacy-Code aus einer alten Bibliothek und ich habe viele Fragen darüber, wie diese Klasse funktioniert. Die Art und Weise, wie ich ServiceLocator verwenden kann, ist auch für mich sehr merkwürdig und diese Strategie ist nicht gut, um das zu verspotten Dienstleistungen für meine Unit Tests . Ich möchte einen neuen ServiceLocator erstellen oder eine Abhängigkeitsinjektionsstrategie (oder einen anderen besseren Ansatz) verwenden.
  2. Die Klasse UserService soll nicht von einem anderen "externen" Dienst wie OrderService verwendet werden. Es ist nur für die UserVxService . Aber vielleicht möchte OrderService in der Zukunft Code aus UserService ...
  3. verwenden
  4. Selbst wenn ich das letzte Problem ignoriere, muss ich mit ServiceLocator eine Menge lookups unter meinem Code machen. Die Möglichkeit, eine zyklische Abhängigkeit zu erzeugen (serviceOne-NachschlagedienstZwei dieser NachschlagedienstDreier NachschlagedienstOne) ist sehr hoch.
  5. Bei diesem Ansatz könnten die VOs wie UserV1VO in meinen nicht versionierten Diensten ( com.organization.api.services ) verwendet werden, aber das kann nicht passieren. Eine gute Architektur lässt etwas nicht zu, was nicht erlaubt ist. Ich habe die Idee, ein neues Projekt zu erstellen, wie zum Beispiel api-services und das com.organization.api.services , um dies zu vermeiden. Ist das eine gute Lösung?

Also ... Ideen?

    
Dherik 02.09.2016, 01:55
quelle

2 Antworten

2

Ein paar Dinge, die ich sehe:

  • Das UserService sollte idealerweise auf einer Schnittstelle basieren. Sie scheinen einen ähnlichen Vertrag zu haben, aber der einzige Unterschied sind ihre Quellen (RemoteEJB, LocalServiceLocator). Diese sollten DTOs zurückgeben

  • UserV1Service extends UserService sollte keine Vererbung verwenden, sondern stattdessen die Komposition bevorzugen. Denken Sie darüber nach, was Sie für v2 des gleichen Dienstes tun müssten. Basierend auf Ihrem Beispiel erhalten Sie UserV2Service extends UserService . Dies ist insbesondere dann nicht ideal, wenn Sie in Ihrer Basisklasse abstrakte Methoden erhalten, die für eine bestimmte Version spezifisch sind. Dann müssen plötzlich andere versionierte Dienste dafür sorgen.

Für den ServiceLocator

  • Es ist besser, wenn Sie in Ihrem Fall ein Framework zur Abhängigkeitsinjektion wie Spring oder vielleicht CDI verwenden. Dies würde nur für Ihren eigenen Code gelten, wenn Ihr Projekt neu ist.

  • Für diejenigen, die schwer zu testen sind, würden Sie die RemoteEJB-Aufrufe in eine eigene Oberfläche umbrechen, die das Nachstellen erleichtert. Die Tests für RemoteEJBs wären dann Integrationstests für dieses Projekt.

  

Die UserService-Klasse soll nicht von einem anderen "externen" Dienst wie OrderService verwendet werden. Es ist nur für den UserVxService. Aber vielleicht möchte OrderService in der Zukunft Code von UserService verwenden

Es ist nichts falsch daran, dass Dienste auf derselben Ebene miteinander kommunizieren.

  

Bei diesem Ansatz könnten die VOs, wie UserV1VO, in meinem verwendet werden   nicht versionierte Dienste (com.organization.api.services), aber dies kann nicht   geschehen. Eine gute Architektur lässt etwas nicht zu, was nicht erlaubt ist.   Ich habe die Idee, ein neues Projekt wie api-services zu kreieren und die   com.organization.api.services dort, um dies zu vermeiden. Ist das gut?   Lösung?

Nur weil du etwas tun kannst, heißt das nicht, dass du es tun solltest. Es scheint zwar eine gute Idee zu sein, die Ebene in ein eigenes Projekt zu unterteilen. In der Realität hält ein Entwickler nichts davon ab, entweder dieselbe Klasse in diesem Projekt neu zu erstellen oder das jar in den Klassenpfad aufzunehmen und dieselbe Klasse zu verwenden. Ich sage nicht, dass es falsch ist, sie zu spalten, nur dass sie aus den richtigen Gründen gespalten werden sollte, anstatt "Was-wäre-wenn-Szenarien".

    
Shiraaz.M 07.09.2016, 22:18
quelle
0

Ich habe diese Lösung (Danke @ Shiraaz.M):

  • Ich entferne alle Erweiterungen in meinen Diensten und lösche die gefährliche ServiceLocator-Klasse. Diese Erbschaften ohne einen guten Zweck und Service Locator sind beide schlechte Ideen. Ich versuche Guice zu verwenden, um die Abhängigkeiten in meine REST-Ressourcen zu injizieren, aber das ist nicht so einfach in meiner Jax-rs Version. Aber meine Dienste sind sehr einfach und einfach zu erstellen, so dass meine Lösung einfach war:

    %Vor%

Und mein UserV1Service:

%Vor%

Mit dieser Strategie ist es einfach, andere Dienste mit Komposition zu verwenden.

  • Wenn nötig, werde ich in Zukunft Guice einführen, um die Abhängigkeiten in die restlichen Ressourcen und Dienste zu injizieren (zumindest in die Dienste) und den Standardkonstruktor aus den Diensten zu entfernen, die Abhängigkeiten haben und denselben Konstruktor in der Tests und Produktion.
  • Über den Punkt 4 habe ich mit dem Team gesprochen und erklärt, wie die Organisation ist. Das Team versteht das gut und niemand bricht diese Architektur.
Dherik 18.10.2016 12:15
quelle