2011-01-05 4 views
3

Ich habe eine interne Unternehmensanwendung (EJB2), die mit einem bestimmten BPM-Anbieter funktioniert. Die aktuelle Implementierung der In-House-Anwendung umfasst das Einziehen eines Objekts, das nur durch die API des Anbieters verfügbar gemacht wird, und das Vornehmen von Änderungen durch die bereitgestellten Methoden in der API.Brauchen Sie Hilfe, ein eng gekoppeltes Design zu verbessern

Ich denke, dass ich ein internes Objekt irgendwie diesem externen zuordnen muss, aber das scheint zu einfach zu sein und ich bin mir nicht ganz sicher, was die beste Strategie dafür ist. Kann jemand etwas darüber erzählen, wie sie in der Vergangenheit mit solch einer Situation umgegangen sind?

Ich möchte diese Software des Herstellers "black box", so dass ich es bei Bedarf leicht ersetzen kann. Was wäre aus Sicht des Designs der beste Ansatz, um ein internes Objekt diesem exponierten API-Objekt zuzuordnen? Denken Sie daran, dass meine Inhouse-App immer noch mit der API kommunizieren muss, also wird es eine Abhängigkeit zwischen den beiden geben, aber ich möchte sie reduzieren, damit ich auch isoliert von dieser Software mit Junit testen kann.

Danke, Jason

+0

Wenn in der App keine bestimmte Einschränkung vorhanden ist, wird in den folgenden Antworten der Standardweg der Abstraktion (mithilfe der Schnittstelle) dargestellt. Ich bin mir sicher, dass du das bereits wusstest, daher bin ich neugierig, ob es etwas Bestimmtes in deiner App gibt, das das schwierig machen könnte.Auch, nicht versuchen, hier zu piggyback, aber wenn Sie wirklich lose gekoppelt machen möchten, können Sie Spring IOC anstelle von "new MyAPIEndpoint();" – Victor

+0

Ich war auf der Suche nach mehr Bestätigung, dass die Schaffung einer Art von Fassade der Weg war. Ich war mir auch nicht sicher, warum es hier nicht gemacht wurde, also dachte ich, ich hätte etwas übersehen. Der Frühling wäre ideal, und ich hoffe, dass er irgendwann in Zukunft auf diesen Rahmen übertragen wird. – JasonH

Antwort

3

Erstellen Sie eine Schnittstelle für die Service-Schicht, intern kann Ihr gesamter Code damit arbeiten. Dann erstellen Sie eine Klasse, die diese Schnittstelle verwendet und die API-Methoden von Drittparteien und als API-Fassade aufruft.

heißt

interface IAPIEndpoint { 
    MyDomainDataEntity getData(); 
} 

class MyAPIEndpoint : IAPIEndpoint { 

    public MyDomainDataEntity getData() { 
     MyDomainDataEntity dataEntity = new MyDomainDataEntity(); 
     // Call the third party api and fill it 
     return dataEntity; 
    } 
} 

Es ist immer eine gute Idee Dritte apis Schnittstelle, so dass Sie nicht ihren Funk bekommen Ihre App Domain Invasion, und Sie können je nach Bedarf tauschen. Sie könnten eine andere Klassenimplementierung erstellen, die einen anderen Dienst vollständig verwendet.

Um es in Code zu verwenden, rufen Sie einfach

IAPIEndpoint endpoint = new MyAPIEndpoint(); // or get it specific to the lang you are using. 

Ihre Sachen auf Schnittstellen auf Basis machen, wenn es mehrere Implementierungen umspannt ist der Weg zu gehen. Es funktioniert auch gut für TDD, so dass Sie die Schnittstelle einfach zu einem lokalen Test austauschen können, der Ihren Domänencode vollständig von der Drittanbieter-API überprüfen kann.

+0

Danke Ryan, ich denke das macht Sinn. Lassen Sie mich eine Frage stellen, um sicherzugehen, dass ich verstehe: Ich kann diesen Ansatz verwenden und die Schnittstelle erstellen - in einem Beispiel kann ich die dritte API nennen, in einer anderen kann ich eine Testimpl der API nennen, damit ich isoliert testen kann . Ist das korrekt? Meine Sorge ist, wie ich mit den Methoden im API-Objekt umgehen werde, wenn ich sie aufrufen muss (meistens set/get, aber es gibt einige Methoden). – JasonH

+0

Es ist immer schwierig, Gemeinsamkeiten zu finden. Ja, die Benutzeroberfläche beschreibt, was Sie in allen Implementierungen konsistent verwenden werden (Klassen, die die Schnittstelle verwenden oder impl in Java World). Ich neige dazu, nur die allgemeinen Methoden, die "generalisiert" werden, in die Hauptschnittstelle zu stellen. Dann können bestimmte spezifische API-Methoden, die von diesen Methoden in einer Implementierung verwendet werden, spezifische Methoden für die Implementierung ausführen. Zum Beispiel haben wir hier einen Matchup-Server und wir rufen eine Schnittstelle für FindMatch(), StartMatch(), CloseMatch() usw. auf. Diese sind in der Schnittstelle. Dann in einem Gamecenter ... –

+0

Implementierung dieser Klasse verwenden wir die GameCenter-Aufrufe, um eine Übereinstimmung zu erhalten, eine Übereinstimmung zu starten, eine Übereinstimmung zu schließen und viele andere Methoden zu verwenden, die diese Aufrufe für GameCenter als private Methoden verwenden. Dann können wir leicht mit einer Test-Implementierung, die lokal ausgeführt wird, und einem anderen Match-up-Server, der selbst gehostet wird, austauschen. Unsere drei Drittanbieter- oder Unique-Anwendungen sind also alle durch die Schnittstelle mit generischen Calls gebräuchlich. HTH-Schnittstellen sind auch sehr häufig in Web-Service-Server/Client-Setups vorhanden, bei denen sich der gesamte Code möglicherweise nicht auf dem Client befindet und nur die Schnittstellen- und Container-Klassen vorhanden sein müssen. –

0

Abstraktion; Implementieren Sie eine DAL, die den Übergang von intern nach extern und zurück bereitstellen wird.

Wenn Sie dann die Anbieter wechseln, bleiben Ihre Interna wertvoll und Sie können den herstellerspezifischen Code ändern. unter der Annahme, dass die Anbieter die gleiche Funktionalität und die miteinander verbundenen Datentypen bereitstellen.

0

Ich werde hier das schwarze Schaf sein und für das YAGNI Prinzip eintreten. Das Problem ist, dass wenn Sie jetzt eine Abstraktionsschicht erstellen, diese der API des Drittanbieters so nahe kommt, dass sie nur eine redundante Schicht ist. Da Sie jetzt nicht wissen, wie eine hypothetische API des zweiten Anbieters aussehen wird, wissen Sie nicht, welche Unterschiede Sie berücksichtigen müssen, und jeder zukünftige Port wird wahrscheinlich eine Nachbearbeitung für diese unvorhergesehenen Unterschiede erfordern.

Wenn Sie ein Testframework benötigen, empfiehlt es sich, Ihre eigene Testimplementierung mit derselben API wie der BPM-Anbieter zu erstellen. Noch besser, fast alle seriösen API-Anbieter bieten eine Art Sandbox-Modus zum Testen. Wenn sie es nicht tun, sollten Sie nach einem fragen.

+0

Karl stimme ich in gewissem Umfang zu. Was jedoch letztendlich passiert, ist, dass, wenn keine formale Schicht zwischen dem Hersteller und der Anwendung existiert, die Implementierung des Lieferanten über Typen und API-Verhalten weiter stromaufwärts auftaucht, als es sollte. Sobald Sie die Anbieter wechseln, werden Sie erkennen, wie stark Sie mit der Implementierung der Anbieter verbunden waren. wohingegen eine Abstraktionsschicht zwingt, zuerst über die Anwendungsanforderungen nachzudenken; die Verkäufertypen und API Kuriositäten abstrahieren. –

+0

Ich stimme zu, dass ich dies normalerweise nicht mache, es sei denn, ich benötige sofort zwei Implementierungen oder einen Webdienst, bei dem wir versuchen, den clientseitigen Code zu begrenzen. Aber zum Testen und TDD-Stil ist es sehr hilfreich. Das Tolle an der Abstraktion ist, dass Sie eine ProductionThirdPartyAPI-Implementierung, eine Testimplementierung und einen Test DevelopmentThirdPartyAPI haben, sodass Sie Entwicklungs- und Produktions-API-Ebenen austauschen können, die sich allein schon lohnen könnten. –

Verwandte Themen