16 Stimmen

Unter Verwendung eines Workflow-Engines, Zustandsmaschinen-Engines oder durch Eigenentwicklung?

Ich bin verwirrt. Ich entwickle ein internes Tool für mein Unternehmen auf Basis von Grails. Eine Komponente in diesem Tool ist ein einfacher Problem-Tracker (eine Helpdesk-Funktion). Ich habe Domänenobjekte wie Problem, Frage und NeuesFeature. Jede dieser Domänenklassen hat unterschiedliche Workflows.

Meine erste Idee war es, meine eigene Zustandsmaschinenfunktionalität innerhalb der Domänenobjekte zu implementieren. Dann habe ich nach Zustandsmaschinen-Engines und Workflow-Engines gegoogelt. Und jetzt bin ich verloren.

Ich würde gerne Kommentare dazu sehen, wie andere Entwickler dieses Problem gelöst haben. Verwendest du Drools, Jbpm, Activiti? Oder eine einfachere Zustandsmaschinen-Engine?

Ich habe einige Dokumentationen zu Drools und Jbpm gelesen. Sie sehen sehr gut aus. Aber es scheint, als ob ich nur einen kleinen Teil der Funktionen dieser Bibliotheken benötige.

Ich verwende dafür Grails, aber es ist natürlich auch einfach, Java-Bibliotheken zu verwenden.

17voto

ams Punkte 56020

Der Hauptwert einer Workflow-Engine ist, dass es möglich macht, die Abläufe durch eine Workflow-Definition-DSL anzupassen. Wenn Sie nicht möchten, dass Benutzer ihre eigenen beliebigen Workflows definieren können, sind Sie besser dran, Ihren eigenen zu erstellen.

Außerdem bieten Workflow-Engines normalerweise die Möglichkeit, sehr lang laufende Geschäftsvorgänge und Regeln zu definieren. Zum Beispiel können Sie einen Workflow für die Genehmigung von Bestellungen haben, bei dem der erste Schritt darin besteht, einige Informationen darüber einzugeben, was gekauft werden muss, dann haben Sie Regeln wie z.B. wenn der Kaufpreis weniger als 100 $ beträgt, sofort genehmigen, wenn er zwischen 100 $ und 2000 $ liegt, kann der Linienmanager genehmigen, wenn es mehr ist, senden Sie es an jemand anderen zur Genehmigung ... usw. Diese Arten von Geschäftsregeln neigen dazu, sich im Laufe der Jahre zu ändern, wenn die Beträge erhöht werden oder sich die Geschäftspolitik eines Unternehmens ändert. Daher macht es in solchen Szenarien Sinn, eine Workflow-Engine zu verwenden. Andere gute Beispiele für komplexe Geschäftsvorgänge, die von einer Workflow-Engine profitieren können, sind das Stellen eines Versicherungsanspruchs, die Genehmigung eines Darlehens oder einer Hypothek, die Prüfung eines Kreditantrags eines Kunden ... usw. Diese Geschäftsvorgänge durchlaufen normalerweise mehrere Personen / Abteilungen und dauern mehrere Stunden bis Tage oder Wochen, um abgeschlossen zu werden.

Regel-Engines eignen sich gut, um komplexe, sich ändernde Regeln aus einer Anwendung herauszuziehen. Angenommen, Sie sind ein Online-Händler, der an Kunden in den USA, Kanada, Großbritannien, Deutschland und Frankreich versendet. Sie sind verpflichtet, Steuern auf die Produkte zu erheben, die Sie in Ihrem Online-Shop verkaufen. Die Regeln für die Berechnung der Steuern sind jedoch von Land zu Land und von Provinz zu Provinz innerhalb eines Landes unterschiedlich. Außerdem sind manche Dinge in einer Provinz von der Steuer befreit, in anderen Provinzen jedoch nicht. Regel-Engines sind ideal für diese Art von komplexen Geschäftsregeln, die sich ändern können, wann immer die Regierung ihre Steuerpolitik ändert. Regel-Engines können Ihnen sofort eine Antwort geben. Sie müssen nur zur Regel-Engine gehen, sagen, dass Sie Regel #10 ausführen möchten und hier sind die Eingaben für Regel #10 x, y, z und Sie erhalten eine Antwort zurück.

Der Hauptunterschied zwischen einer Regel-Engine und einer Workflow-Engine besteht darin, dass eine Regel-Engine den Status der Transaktion nicht verfolgt. Sie sollte zustandslos sein und nur mit den von Ihnen bereitgestellten Eingaben arbeiten. Eine Workflow-Engine ist zustandsbehaftet, sie muss wissen, in welchem aktuellen Zustand sich der Workflow befindet, und diesen Zustand in einer Datenbank speichern. Workflow-Engines warten auch auf Eingaben von externen Quellen wie Personen oder Systemen.

Basierend auf der Beschreibung Ihrer App würde ich einfach einige Groovy-Klassen schreiben, um den nächsten Zustand eines Tickets zu berechnen und sicherzustellen, dass die Klasse gut dokumentiert und einfach zu aktualisieren ist in ein paar Jahren. Ich denke, Regel-Engines und Workflow-Engines sind für Ihre Situation überdimensioniert, der Zeitaufwand für deren Einrichtung und Nutzung ist viel größer, als es dauern würde, den Code in Groovy zu schreiben. Wenn Sie im Laufe der Zeit feststellen, dass Sie die Komplexität von Regel-Engines und Workflow-Engines benötigen, würde ich den Preis damals bezahlen, anstatt jetzt, es einfach zu halten ist immer die beste Wahl.

6voto

Frank Zhang Punkte 792

Ich kann der obigen Antwort von AMS nur zustimmen, und noch etwas hinzufügen: In den meisten Szenarien ist die Verwendung von Workflow-/Regel-Engines übertrieben und unnötig. KISS Halte es einfach und dummist immer die beste Wahl. Und Occams Rasiermesser besagt auch: "Entitäten sollten nicht unnötig vervielfacht werden".

Nach meiner eigenen Arbeitserfahrung bei Alibaba machen die meisten mit Workflow-/Regel-Engines ausgestatteten Anwendungen die Wartung zu einem Albtraum, und die Leute, die später zum Projekt kommen, werden es zu schätzen wissen, wenn Sie eine vereinfachte Implementierung anstelle der blinden Wahl einer Workflow-/Regel-Engine verwenden.

Gibt es also eine Richtlinie, die sagt, wann man einen Workflow verwenden soll oder nicht? Ehrlich gesagt weiß ich es nicht, aber was ich weiß ist, dass wir definitiv nicht immer eine Workflow-Engine verwenden sollten, wenn die Geschäftslogik in einem Fluss ist. Denn wenn wir das tun würden, könnte jede Geschäftslogik in einem Flussdiagramm dargestellt werden.

Zuletzt, eine der besten Entscheidungen, die ich letztes Jahr getroffen habe, war die Neugestaltung einer Anwendung, um Drools durch ein Groovy-Skript zu ersetzen, was das gesamte System viel einfacher, simpler und schneller gemacht hat.

1voto

Mike Punkte 18362

Der 'State machine' ist ein gängiges Entwurfsmuster, also was gibt dir drools eigentlich? Ich schätze drools persönlich wegen seiner 'Abfragesprache', das ist es, was es zum Leuchten bringt. Praktisch haben Sie etwas Ähnliches wie 'SQL, um Objekte aus Ihrem Heap abzufragen'. Genau wie SQL Ihnen eine 'deklarative' Programmierweise gibt, beschreibt der drools when-Block, wann der Zustandsübergang auf deklarative Weise startet. Drools wurde entworfen, um standardmäßig zustandsbehaftet zu sein und der Zustand sind alle Fakten (POJOs), die in die drools-Sitzung eingefügt wurden.

Lassen Sie mich Ihnen einen einfachen Anwendungsfall vorschlagen. Sie müssen eine Anwendung für ein Mobilfunkunternehmen schreiben, um Telefonanrufe zu verwalten:
Wenn Anrufer 1 an den Angerufenen 2 anruft und dieser in diesem MOMENT nicht 'beschäftigt' ist, verbinden sie.
Wenn der Angerufene beschäftigt ist, setzen Sie den Anruf 7 Sekunden lang fort und wenn der Angerufene seinen ursprünglichen Anruf WÄHREND dieser Zeit ablehnt, verbinden Sie sie sofort.
Wenn der Angerufene innerhalb von 7 Sekunden nicht auflegt, beenden Sie den Anruf mit der Nachricht 'Angerufener ist beschäftigt'.

Ein einfacher Dreifach-IF-Anweisungsgeschäftsmethoden wurde schnell zu einer recht komplexen und fehleranfälligen technischen Aufgabe. Ich stelle mir im Hintergrund Timer vor, die ich vor 5 bis 10 Jahren viel gesehen habe, oder neuere wie ScheduledThreadPoolExecutor. Und was passiert, wenn sich der Zustand WÄHREND der geplanten Verzögerung ändert? Werden Sie immer noch warten, bis das Ende erreicht ist, um die Bedingung neu zu berechnen? Wenn eine solche Bedingung in Ihrer Anwendung relativ häufig vorkommt oder der Zeitraum relativ lang ist, werden Sie den 'Kontext' im Gedächtnis behalten? Sie müssten Futures verfolgen und sie abbrechen oder eine BlockingQueue verwenden. Man müsste für solche Fälle für jede Person eine Warteschlange führen, weil jede Person potenziell von jemandem angerufen werden kann. Das traditionelle OOP sagt 'Sie sollten das Verhalten an Ihre Domänenentitäten anhängen'. Mit diesem Ansatz werden Sie Ihre Geschäftsobjekte mit ziemlich komplexen technischen Dingen überladen, selbst wenn Sie einige Muster zur Vereinfachung (Kapselung) der Komplexität verwenden würden, fängt Ihre 'State machine' an, sich zwischen mehreren Komponenten zu verteilen, es wird noch schlimmer, wenn Sie 'schichtweise' vorgehen, denn dann werden Sie Datenstrukturen für den Zustandskram erstellen, wie Map>. Am nächsten Tag kommt Ihr Kunde zu Ihnen und sagt: 'Hey, ich habe einen weiteren einfachen Anwendungsfall für Sie rund um Telefonanrufe'.

Drools löst solche Probleme 'natürlich', weil es einen völlig anderen Ansatz verwendet. Es verfolgt alle Objekte im Arbeitsgedächtnis (es verfolgt die Regelform) und wenn es soweit ist, kann drools einfach sagen, ob Ihre Regel dazu berechtigt ist, ausgeführt zu werden oder nicht (Rete-Algorithmus aus dem Jahr 1979). Wenn sich der Zustand ändert, bewertet drools die Bedingung für jede Regel auf effiziente Weise neu und fügt oder entfernt entsprechende Regeln aus der 'Agenda' (Ausführungsqueue). Alle Objekte, die Sie in das 'Arbeitsgedächtnis' eingefügt haben, bilden einen 'Zustand', auf den sich jede Regel beziehen kann. Sie können einige Diagramme und Tests für den oben beschriebenen Anwendungsfall und die tatsächliche drools-Regelimplementierung hier finden.

Verwenden Sie die richtigen Werkzeuge für Ihre Aufgaben. Wenn Sie eine for-Schleife für eine Sammlung von Entitäten mit dem Zustandsobjekt innerhalb mit 3-5 Feldern benötigen, setzen Sie nicht 'State machine' in den Titel. Wenn Sie wirklich Probleme wie 'kontinuierliche Verhaltensänderung' oder komplexe Ursache-Wirkungsabhängigkeiten zwischen Ereignissen in Ihrem System haben, ist drools gut und zeitbewährte Open-Source-Rete-Algorithmus-Implementierung. Versuchen Sie nicht, alles zu verwenden, was beworben wird, gehen Sie in die Details, verstehen Sie, was Ihren Anforderungen entspricht.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X