Die Aufgabe besteht darin, einen Teil meiner Java-Webanwendung zu erstellen, der es mir ermöglicht, auf einfache Weise kleine Codes in einer zusammengesetzten Weise auszuführen. Die Aufgabe besteht darin, dem Benutzer zu ermöglichen, "Aktionen" in beliebiger Reihenfolge zu erstellen. Worum ich mich bemühe, ist die Weitergabe von Parametern an meine Aktionen.
Alles beginnt mit der Aktionsschnittstelle:
%Vor%Wenn die Aktion gelöst ist, wird der Code ausgeführt. Der Code kann alles sein: Aufruf einer Methode in Java, Ausführung von Javascript ...
Hier ist der "Kontext" das Problem für mich. Jede Aktion wird in einem bestimmten Kontext ausgeführt. Der Benutzer, der die Aktion erstellt, kann angeben, welches Objekt aus dem Konzept abgerufen werden soll, z. B. der Benutzer, der die aktuelle Aktion auflöst, oder andere Objekte, die in der spezifischen Schnittstelle der Aktion angegeben sind.
Beispiel, schauen wir uns diese Aktion an:
%Vor%Es ist ein einfacher Wrapper, der eine Aktion in Javascript mit Nashorn aufruft. Die Parameter können alles sein: Objekte mit bestimmten IDs im DB, int / String / boolesche Werte, die vom Benutzer konfiguriert wurden ...
Der Code einer Aktion kann folgendermaßen aussehen:
%Vor%So kann die Aktion Laufzeitparameter (z. B .: Benutzer, der die Aktion ausführt ...) und statische Parameter (die beim Laden der Aktion erstellt werden - z. B. aus einer Konfigurationsdatei) und alles aus dem Konzept abrufen. Außerdem kann der Benutzer z. B. Verweise auf das Objekt in den Parametern angeben, die zur Laufzeit injiziert werden.
Aktionen können auch verschachtelt / dekoriert werden, um die vollständige Komposition zu erreichen. Zum Beispiel:
%Vor%Damit können Aktionen leicht erstellt werden:
%Vor%Wenn Sie all das wissen, was ist am besten geeignet, um die Kontextklasse zu entwerfen? Sollte es in mehrere Elemente aufgeteilt werden? Der Kampf besteht darin, alles, was zur Laufzeit benötigt wird, in die Klasse zu injizieren und sicher zu stellen, dass keine Konflikte mit möglichen eingepackten Aktionen auftreten.
Die grundlegende Implementierung von Context ist verantwortlich für:
Ich fühle, dass es zu viel macht. Das Design wird von den Concept-Klassen beeinflusst, die viele Verantwortlichkeiten besitzen und fragmentiert sein sollten (momentan ist jeder Teil der Anwendung mit dem Konzept verbunden). Aber wie ? Hier ist, was ich versuche, saubere Codierung zu erreichen:
In einer objektorientierten Art und methodenorientiert, wie löst man dieses spezifische Designproblem?
edit: entfernt öffentlichen Deklarator in Methode in der Schnittstelle
edit 2: Ich hatte viele interessante Lösungen, aber diejenige, die mir mehr Sinn machte, war diejenige, in der jede Aktion mit einer bestimmten Art von Kontext parametrisiert wird. Ich habe die Dinge als solche neu organisiert:
Ich hatte das Action
interface generisch auf seinem Context
:
Und dann könnte Context
entweder eine Markierungsschnittstelle, eine Schnittstelle, die einen Vertrag erzwingt, oder eine abstrakte Klasse mit Standardmethodenimplementierungen sein:
Dann könnten Sie tun:
%Vor% Und ein Action
, der den Benutzer anmeldet, könnte sein:
Für einen umschlossenen Action
würde ich einen WrapperContext
-Kontext verwenden:
Implementierung:
%Vor% Nun könnte Ihr DummyWrapperAction
wie folgt aussehen:
Die Idee besteht darin, auch Kontexte zu umhüllen. Sie können dieses Design verbessern, indem Sie es ermöglichen, Kontexte zu ketten oder zu dekorieren, und abstrakte Klassen verwenden, die für die Aufgaben zuständig sind, die allen Kontexten gemeinsam sind.
Interpreter GoF-Muster, interpretierter Baum kann in gewisser Weise externalisiert werden. Sie können jeden Knoten dekorieren und auf Ihre Anfrage antworten. Noch eine Sache: action interface sollte mindestens zwei Methoden haben, wenn die Repräsentation extern ist (dh vom Benutzer gemacht): eine für die Gültigkeit des Baumes (zB ein Knoten, der zwei Kinder benötigt, muss genau diese Kinder haben) und einen für die Ausführung der Baum.
Bearbeiten: Hier ist ein Beispiel
%Vor%Ich hoffe, es ist jetzt klar.