2012-09-11 6 views
8

Entschuldigen Sie jede Ignoranz hier, ich bin ziemlich neu zu DDD so sei sanft.DDD in einem konfigurierbaren regelgesteuerten System

Ich arbeite an einem großen konfigurationsgesteuerten Datenverwaltungssystem. Das System wird durch Spezifizieren von Konfigurationselementen (wie Geschäftsregeln, Prozessen und Validierungen) in einer externen Syntax erstellt. Sagen wir einfach, dass die Syntax ein Konglomerat aus Groovy basierten DSL und Drools war.

Ich mag die Ideen der Einfachheit, die DDD bietet, insbesondere Infrastruktur-Anliegen von den Kernkonzepten der Domäne zu trennen.

Allerdings habe ich Schwierigkeiten, einige der Konzepte von DDD aufgrund der konfigurierbaren Natur des Systems anzuwenden. Sowohl Verhalten (Prozesse), Validierung und Geschäftsregeln sind außerhalb des Systems definiert. Daher haben die Entitäten in der Domäne intrinsisch kein eigenes Verhalten. Eher heikel für das "Validator" -Ding oder die "Rules Engine" oder die "Workflow Engine".

Ich werde mit einem Beispiel klären. Nehmen wir an, mein System verwaltet Mitarbeiter für ein Unternehmen. Ohne zu viel darüber nachzudenken, können Sie sich vorstellen, dass ich in meiner Domäne eine Mitarbeiter-Entität und eine Unternehmens-Entität habe.

Nach DDD versuche ich ein Szenario zu modellieren, in dem ein Mitarbeiter befördert wird. Möglicherweise wird eine neue Methode auf dem Mitarbeiter namens promote (Employee.promote) angezeigt. Wir könnten eine Geschäftsregel haben, die angibt, dass ein Mitarbeiter nicht zweimal im selben Jahr befördert werden kann (ja, das ist alles erfunden). Ich kann daher so etwas wie habe:

public void promote(EmployeeLevel newLevel) { 
    if (hasBeenPromotedThisYear(this) { 
    throw new InvalidPromotionException 

Nun, in der Anwendung, die ich mit diesem Geschäft Regel arbeite würde zu einem Regel-Engine externalisiert werden. Nach DDD könnte ich etwas tun wie:

if(promotionRules.isEligibleForPromotion(this) 

Um meine Regeln zu externalisieren. Das System ist jedoch wesentlich allgemeiner. Die "Promotion" -Operation selbst wird als "Prozess" durch externe Konfiguration definiert. Also würde ich zur Kompilierzeit nicht einmal wissen, ob ich für diesen Mitarbeiter eine "Promotion" -Operation zur Verfügung habe. So wird mein Mitarbeiter-Objekt aus einer Code-Perspektive ziemlich leer und delegiert alle Funktionen an die Konfiguration. Es könnte etwa so aussehen:

public class Employee { 
    public void execute(Process process) 

Oder alternativ

public class EmployeeProcess { 
    public void process(Employee employee) 

Meine Frage ist: Hat DDD auch Sinn in dieser Anwendung machen? Soll ich stattdessen nur die Zusammenarbeit von Prozessen, Validierungen, Geschäftsregeln (Rules Engine) im Nicht-DDD-Sinn modellieren?

Ich mag die Zwiebel-Architektur, und kann UI -> App Services -> Core -> Infrastruktur, um eine nette Trennung von Bedenken zu halten. Aber der Kern könnte die oben erwähnten Kollaborateure sein, im Gegensatz zu echten "Domänenkonzepten".

Ein Teil von mir glaubt, dass in diesem Fall die "Domänenkonzepte" die Validatoren, Prozessoren, Geschäftsregeln sind, weil sie die allgegenwärtige Sprache bilden, über die wir reden, wenn wir unser System diskutieren. In diesem Fall hätte ich Entitäten ohne echtes Verhalten (zum größten Teil) und Domänenkonzepte in Bezug auf Prozessoren, Validierer, Rules Engine, die das Verhalten im System realisieren.

Hinzufügen ein wenig mehr Info. In Anbetracht meiner obigen Frage arbeitete ich an einer Lösung, die wie folgt aussehen würde:

org.example.

app

org.example.domain - Mitarbeiter - Firmen - EmployeeLevel

org.example.domain.shared - Prozess - BusinessRule - Validator

org.example.infrastructure

Hoffentlich fügt dieses kleine Schnipsel ein wenig Klarheit hinzu.

Die Konzepte Process, BusinessRule und Validator würden also innerhalb der Domäne liegen, würden aber das Domänenmodell in Bezug auf die Dinge unterstützen, die das System tut.

Antwort

2

Aus Wikipedia:

Domain-Driven Design (DDD) ist ein Ansatz Software, die von tief für komplexen Anforderungen an die Entwicklung, die Umsetzung zu einem sich entwickelnden Modell der Kerngeschäftskonzepte verbindet.

Ich glaube, dass Validator, Prozess, Regel sind nicht Ihre Kerngeschäftskonzepte. Das sind ziemlich häufige Software-Abstraktionen.

Ich bin kein großer Fan von "by-the-Book" DDD, aber um mehr "domain-driven" sollten Ihre DSL und Ihre Regeln tatsächlich um Ihre Geschäftskonzepte gebaut werden, um mehr Sinn zu geben .

Unter der Haube können Sie immer noch Validatoren, Prozesse, Manager, Executoren usw. verwenden, aber Ihre DSL/Regeln werden besser lesbar sein, wenn Sie Geschäftskonzepte und keine Software-Abstraktionen verwenden.

AKTUALISIERT: Da Sie Groovy für die Definition Ihrer DSL verwenden, können Sie die dynamische Namenserweiterungs- und Builder-Funktionalität von Groovy verwenden, um lesbare Regeln und Klassen zu erstellen. Sie können auch das "convention over configuration" -Prinzip nutzen, um einige Logik einzubinden. Zum Beispiel in Groovy können Sie versuchen, etwas Ähnliches zu konstruieren:

if (employee is "promotable") { 
    start "promotion" for employee 
} 

is wird ein Verfahren auf einem Basis Domain-Objekt, das für die Existenz des überprüfen lassen EmployeePromotableValidator Klasse sagen, was an sich auch ein Groovy sein kann Klasse, die Groovys DSL-Ausdruckskraft nutzt.

class EmployeePromotableValidator extends Validator<Employee> { 

    boolean validate(Employee employee) { 
    employee.age > 25 && employee.workingYears > 2 
    } 

} 

start wird ein Verfahren auf der Basis Regelskript sein, die für EmployeePromotionProcess Klasse suchen, das kann wiederum eine Groovy-Klasse sein.

Spezifikation Muster in diesem Fall sind sehr einfach, weil es im Grunde Teil der Sprache wird:

if (employee is "promotable" && 
    employee is "advanced" && 
    employee.salary < 10000) { 
    start("salary increase", "10%") for employee 
} 

Im Allgemeinen DSLs mit Hilfe von (semi-) funktionalen Sprachen wie Groovy/Scala können verwendet werden, um Software-Abstraktionen zu verbergen und Ihre Geschäftslogik im Code stärker hervorzuheben. Mit Plain Java werden Sie am Ende eine Menge Code haben, der alle Ihre Absichten verbergen wird.

+0

Danke für die Antwort. Das Modell wird sicherlich Geschäftskonzepte enthalten (entsprechend dem Beispiel würde es eine Mitarbeiter-Entität und eine Firmen-Entität mit geeigneten Beziehungen geben). Es sind nur diese Wesen, die größtenteils nackt sind. Also, wenn ich Ihnen recht folge, würden dann die Prozesse, Regeln und Validierer in der Domäne geteilt werden (nach dem Spezifikationsmuster)? Das war der Weg, den ich gehen wollte. – noplay

+0

Siehe das Update der Antwort –

+0

Danke für das Update. Ich bin ziemlich sicher, dass die Geschäftskonzepte im Domänenmodell eine zentrale Rolle spielen werden. In der Konfiguration wird viel Arbeit erledigt, aber es gibt viele Kerngeschäftskonzepte, die in der doman aktiv sein werden. – noplay

1

Es hängt davon ab, was genau Ihre Geschäftsdomäne ist.

Wenn Sie große zusätzliche konfigurierbare crm etwas etwas Konstruktor tun alles Anwendung erstellen werden - dann wird Ihr Unternehmen Domain um das möglich zu machen, damit Substantive wie Process, Executors usw. Teil Ihrer Domain sind.

Wenn Sie eine Anwendung erstellen, die Informationen über Mitarbeiter und deren Werbekampagnen verfolgen soll, dann dreht sich Ihre Geschäftsdomäne um Mitarbeiter, Gehaltsschecks, Leistungsmessungen. Behandeln Sie in diesem Fall Process, Executors und ähnliche Objekte als Eindringlinge in Ihre Domäne.

Auf einer Ebene - sogar Programmiersprache selbst ist ein invasives Werkzeug, das die Lösung des Problems, das Sie in Ihrem Kopf zeichnen, verwischt. Aber es ist notwendig - sonst könnten Sie es nicht materialisieren.

+0

Danke für die Eingabe. In der Regel habe ich gesehen, dass das Spezifikationsmuster in einem freigegebenen Paket/Kontext in die Domäne fällt. Würde nicht verarbeiten, Validatoren, et. al. macht es dann Sinn, auch in die Domäne zu fallen, ähnlich wie ich es bei Spezifikationen gesehen habe? Ich glaube, dass die Implementierung auf diesen Schnittstellen/Basisklassen in die Infrastruktur fällt. – noplay