Freigeben über


Dieser Artikel wurde maschinell übersetzt.

Domäne-Modelle

Verwenden das Domänen Modell Muster

Udi Dahan

In diesem Artikel werden die folgenden Themen behandelt:

  • Domäne Modell Muster
  • Szenarien für das Domänen Modell-Muster
  • Domäne-Ereignisse
  • Das Unternehmen beibehalten in der Domäne
In diesem Artikel werden die folgenden Technologien verwendet:
Domäne Modell Muster

In diesem Artikel wir Gründe zu (und nicht um) einsetzen durchlaufen das Domänen Modell Muster die Vorteile, es bringt sowie bieten einige praktische Tipps auf die Gesamtlösung so einfach wie möglich zu halten.

Inhalt

Worum geht es dabei genau?
Gründe nicht mit das Domänenmodell
Technologie
Gründe für das Domänenmodell verwenden
Szenarien für das Domänenmodell nicht verwenden
Szenarien für das Domänenmodell mit
Weitere komplexe Interaktionen
Cross-Cutting Geschäftsregeln
Domäne-Ereignisse und ihre Aufrufer
Explizite Domain-Ereignisse
Testbarkeit
Befehle und Abfragen
Beibehalten des Business in der Domäne
Parallelität
Eine umfassende Lösung suchen
Zitierte

Wenn Sie war mir stammen vor wenigen Jahren und mich gebeten, wenn ich jemals das Domänen Modell Muster verwendet, die ich mit einem absoluten "Ja". geantwortet haben würde Meinem Verständnis des Musters sicher war. Ich musste unterstützenden Technologien, die es funktioniert.

Aber ich hätte völlig falsch.

Meine Kenntnisse im Laufe der Jahre entwickelt hat, und ich habe eine Zuschreibung für wie eine Anwendung von sich selbst mit diesen derselben Domäne datengesteuerten Prinzipien ausrichten profitieren kann erlangt.

In diesem Artikel wir, werde über wechseln, warum wir die berücksichtigen, verwenden das Domänen Modell Muster auch würden möchten (wie auch Warum nicht), die Vorteile er sollte, bringen Sie Ihre Interaktion mit anderen Teilen einer Anwendung und der Funktionen wir würden von unterstützenden Technologien bereitgestellt werden soll und Erläutern Sie einige praktische Tipps auf die Gesamtlösung so einfach wie möglich zu halten.

Worum geht es dabei genau?

Der Autor der Domäne Modell Muster, Martin Fowler bietet diese Definition (Fowler, 2003):

Ein Objektmodell der Domäne, die Verhalten und Daten enthält.

Um die Wahrheit zu sagen, kann diese Definition an fast jeder Codeabschnitt interpretiert werden, einen ziemlich guten Grund, warum ich dachte ich wurde das Muster verwenden, wenn in der Tat ich true, wenn die ursprüngliche Absicht war nicht.

Wir untersuchen tiefer.

Gründe nicht mit das Domänenmodell

In den ursprüngliche Beschreibung folgenden Text, ich hatte ursprünglich durchgebrannt hinter dieser harmlos Textpassage, jedoch herausstellt, dass viele wichtige Entscheidungen auf verstehen Sie hinge.

Da das Verhalten des Unternehmens zu viel Änderung ist, ist es wichtig, zu ändern, erstellen und diese Schicht problemlos testen. Daher sollten Sie das Minimum der Kopplung von das Domänenmodell auf anderen Ebenen im System.

So eine Ursache nicht damit ist das Domänen Modell Muster Wenn das Unternehmen, das Ihre Software zu automatisieren, ist, nicht viel ändern. Das ist nicht, dass es überhaupt nicht geändert wird, jedoch, die nicht die zugrunde liegende Regeln diktieren, wie Unternehmen erfolgt sind sehr dynamische. Während andere Faktoren technologischen und Umgebung ändern können, ist dies nicht im Kontext des dieses Muster.

Einige Beispiele hierfür sind mehrere Datenbanken (z. B. SQL Server und Oracle) oder mehrere UI-Technologien (Windows, Web, Mobile und usw.) unterstützen. Wenn sich das Verhalten des Unternehmens nicht geändert hat, rechtfertigen diese nicht die Verwendung des Musters Modell Domäne. Besteht darin, eine sagen nicht abrufen, die eine großartige Umgang des Wertes über die Technologien, die das Muster, aber wir ehrlich, über welche Regeln müssen unterstützen wir unterbrechen konnte und warum nicht zu.

Gründe für das Domänenmodell verwenden

In diesen Fällen, in denen das Verhalten des Unternehmens zu viel Änderung ist, müssen ein Domänenmodell die Gesamtkosten für diese Änderungen verringern. Müssen das Verhalten des Unternehmens, die wahrscheinlich ändert eingekapselt in einen einzelnen Teil unserer Software verringert die Zeitspanne, wir müssen eine Änderung durchführen, da er alle an einem Ort ausgeführt wird. Durch diesen Code so weit wie möglich zu isolieren, reduzieren wir die Wahrscheinlichkeit von Änderungen an anderen Orten aufteilen, sodass daher verringert den Zeitaufwand für das System zu stabilisieren.

Szenarien für das Domänenmodell nicht verwenden

Dies führt uns zu dem Feld. 1 am häufigsten verwendeten Fallacy über Domänenmodelle verwenden. Ich selbst wurde diese false Annahme für eine Anzahl von Jahren, guilty und sehen jetzt, wo es mir astray führte.

Fallacy: Alle permanenten-Objektmodell ist ein Domänenmodell

Zunächst wird ein beständiges Objektmodell nicht grundsätzlich die Verhalten des Unternehmens gekapselt, die wahrscheinlich geändert werden. Zweitens kann ein beständiges Objektmodell Funktionalität enthalten, die nicht geändert wird.

Die Art dieses Fallacy ähnelt der besagt, dass alle Schraubendreher Hammer ist. Zwar Sie können (versuchen) Hammer-in Nägel mit einem Schraubendreher, Sie werden nicht sehr effektiv auf diese Weise zu tun. Eine konnte kaum sagen Sie true, wenn das Muster Hammer-werden wurden.

Onlineschalten dieser wieder konkrete Szenarien, die wir alle wissen und Liebe, betrachten die ever-present Anforderung, dass e-Mail-Adresse eines Benutzers eindeutig sein sollte.

Für eine Weile dachte ich, dass der gesamte Punkt müssen ein Domänenmodell wurde Anforderungen aussehen würde es implementiert werden. Wenn wir die Anleitungen in Betracht, die das Domänenmodell ist zum Sammeln von diesen Unternehmen Verhaltensweisen, die geändert werden ziehen, können wir jedoch, dass diese Anforderung die Mold passt angezeigt. Es ist wahrscheinlich, dass diese Anforderung nie geändert wird.

Daher auswählen, eine solche Anforderung in Teil des Systems implementieren, die zum Kapseln der flüchtige Teile des Unternehmens wenig sinnvoll ist möglicherweise schwierig zu implementieren, und möglicherweise nicht ausführen, die gut. Schalten alle e-Mail-Adressen in den Speicher würde wahrscheinlich Sie gesperrt bis Leistung Polizei erhalten. Müssen auch das Domänenmodell einige Dienst aufrufen, ruft die die Datenbank, ob die e-Mail-Adresse ist es ist nicht erforderlich. Eine unique-Einschränkung in der Datenbank würde ausreichend.

Diese Pragmatische denken ist sehr viel den Kern der Domäne Modell Muster und Domäne-driven Design und was Dinge einfach gehalten wird auch als wir Anforderungen komplizierter als das einfache e-Mail-Eindeutigkeit lösen.

Szenarien für das Domänenmodell mit

Geschäftsregeln, die an, wenn bestimmte Aktionen dürfen sind gute Kandidaten für in einem Domänenmodell implementiert wird.

Z. B. würde in einem e-Commerce-System eine Regel, in der Ihnen mitgeteilt wird, dass ein Kunde mehr als 1.000 € in unbezahlten Bestellungen möglicherweise wahrscheinlich im Domänenmodell gehören. Beachten Sie, dass diese Regel mehrere Entitäten umfasst und müssten in einer Vielzahl von Anwendungsfällen ausgewertet werden.

Natürlich würden in einem bestimmten Domänenmodell Wir erwarten viele diese Arten von Regeln, einschließlich Fällen einige Regeln andere überschreiben. In unserem Beispiel oben Wenn der Benutzer eine Änderung an einer Bestellung die Konto-Manager-Manager ist für das Konto der Debitor gehört und anschließend die vorherige Regel gilt nicht.

Möglicherweise unnötig Zeit aufrufen, über welche Regeln müssen in die Anwendungsfälle anwenden und ausdenken schnell mit einer Liste von Entitäten und Beziehungen zwischen Ihnen angezeigt, das "big Design vorab", agile Methoden für Rail, das eschewing. Allerdings sind die Geschäftsregeln und Anwendungsfälle die sehr Gründe, die wir das Domänen Modell Muster an erster Stelle anwenden.

Wenn diese Art von Problemen in der Vergangenheit zu lösen, ich würde nicht zweimal betrachtet haben und würde eine Customer-Klasse mit einer Auflistung von Order-Objekten schnell entworfen haben. Aber unsere Regeln bisher nur eine einzelne Eigenschaft auf Customer stattdessen – UnpaidOrdersAmount. Wir konnten mehrere Regeln durchlaufen und nie tatsächlich in etwas klar auf eine Auflistung von Bestellungen verweist ausgeführt. In diesem Fall agile Maxim "Sie sind nicht gonna benötigt" (YAGNI) sollten verhindern uns Erstellen der Auflistung.

Beim Betrachten der zum Beibehalten dieses Diagramm von Objekten finden wir es möglicherweise zweckmäßig unterstützende Objekte und Auflistungen unterhalb hinzuzufügen. Wir müssen klar Implementierungsdetails und Core Business Verhaltensweisen, die die Verantwortung für das Domänenmodell unterscheiden.

Weitere komplexe Interaktionen

Berücksichtigen Sie die Anforderung, wenn ein Kunde mehr als $ 10.000 lohnt sich der Einkäufe mit unserer Firma vorgenommen hat, Sie ein "bevorzugte" Kunde sind. Wenn ein Kunde ein Bevorzugter Kunde wird, sollte das System Ihnen per E-mail Benachrichtigen der Vorteile von unserer Anwendung bevorzugte Kunden senden.

Was dieses Szenario unterscheidet die eindeutige e-Mail-Adresse Anforderung, die zuvor beschriebenen macht, ist, dass diese Interaktion unbedingt das Domänenmodell betroffen sind. Eine Möglichkeit ist, diese Logik im Code implementieren, die das Domänenmodell wie folgt aufgerufen:

public void SubmitOrder(OrderData data)
{ 
   bool wasPreferredBefore = customer.IsPreferred;
   // call the domain model for regular order submit logic
   if (customer.IsPreferred && !wasPreferredBefore)
      // send email    
} 

Ein Problem, das der Beispielcode vermieden wird den Betrag, der darstellt, wenn ein Debitor bevorzugt wird überprüft. Logik entsprechend ist anvertraut dem Modell Domäne.

Leider können wir sehen, dass der Beispielcode bloated werden weitere Regeln zum System hinzugefügt werden, die ausgewertet werden, wenn Aufträge gesendet werden muss-pflichtig ist. Selbst wenn wir diesen Code in das Domänenmodell verschieben, würden wir noch die folgenden Probleme gelassen werden.

Cross-Cutting Geschäftsregeln

Möglicherweise andere Anwendungsfälle, die der Debitor bevorzugt wird. Wir möchten nicht zum Duplizieren der Logik an mehreren Orten (ob es im Domänenmodell oder nicht ist) haben, besonders weil, Umgestaltung eine extrahierte Methode würde weiterhin erfordern ursprünglichen bevorzugten Zustand des Kunden erfassen.

Wir müssen möglicherweise sogar so weit gehen Sie als zu enthalten eine Art abfangen/aspektorientierten Programmierung (AOP) Methode, um die Duplizierung zu vermeiden.

Anscheinend möchten wir besser unser Ansatz überdenken möchten, bevor wir uns auf Occam des Razor Ausschneiden. Unsere Anforderungen erneut betrachten kann uns einige Richtung.

Wenn ein Kunde eine [etwas] das System geworden ist [etwas tun].

Wir scheint zu fehlen eine gute Möglichkeit Darstellung dieses Musters Anforderung Obwohl dies wie etwas sound, dass ein ereignisbasierten Modell gut verarbeiten konnte. Auf diese Weise Wenn wir erforderlichen führen weitere "sollte den etwas tun" Teil, wir konnte problemlos implementieren, die als zusätzliche-Ereignishandler.

Domäne-Ereignisse und ihre Aufrufer

Domäne-Ereignisse sind die Möglichkeit, wir ausdrücklich darzustellen, den ersten Teil der Anforderung beschrieben:

Wenn ein [ein] ein [etwas] geworden ist...

Während wir diese Ereignisse auf Entitäten selbst implementieren können, kann es vorteilhaft, Sie auf der Ebene der gesamten Domäne zugänglich sein. Wir vergleichen die Dienstschicht in beiden Fällen Verhalten:

public void SubmitOrder(OrderData data)
{ 
   var customer = GetCustomer(data.CustomerId);
   var sendEmail = delegate { /* send email */ };
   customer.BecamePreferred += sendEmail;
   // call the domain model for the rest of the regular order submit logic
   customer.BecamePreferred -= sendEmail; // to avoid leaking memory
} 

Es ist zwar schön nicht den Zustand vor und nach dem Aufruf überprüfen müssen, haben wir dieser Komplexität mit abonnieren und Entfernen von Abonnements aus der Domäne-Ereignis gehandelt wurde. Außerdem sollte nicht Code, der in allen Fällen verwendet das Domänenmodell aufruft verfügen, zu wissen, wenn ein Kunde bevorzugte es werden kann. Bei direkt der Code mit dem Kunden Interaktion nicht solche ein großes Problem. Jedoch sollten Sie beim Senden eines Auftrags können wir den Bestand eines der Bestellung Produkte unter den Schwellenwert Beschaffung bringen – wir möchten nicht, dass Ereignis im Code zu behandeln.

Es wäre besser, wenn wir hätte jedes Ereignis von einer dedizierten Klasse behandelt werden, die nicht mit jedem bestimmten Anwendungsfall behandeln, aber konnte Bedarf alle Anwendungsfälle generisch aktiviert werden. Hier ist eine solche Klasse aussehen würde:

public class CustomerBecamePreferredHandler : Handles<CustomerBecamePreferred>
{ 
   public void Handle(CustomerBecamePreferred args)
   {
      // send email to args.Customer
   }
} 

Wir müssen sprechen, über welche Art von Infrastruktur dieser Klasse wie von Zauberhand vornehmen, erhalten bei Bedarf aufgerufen, aber betrachten, was des ursprünglichen Codes Absenden Reihenfolge übrig ist:

public void SubmitOrder(OrderData data)
{ 
   // call the domain model for regular order submit logic
} 

Ist als sauber und einfach wie eine hoffen konnte – unser Code muss nicht Kenntnisse über Ereignisse.

Explizite Domain-Ereignisse

In der CustomerBecamePreferredHandler-Klasse, die wir Siehe Verweis auf ein CustomerBecamePreferred aufgerufen – eine explizite Darstellung im Code des Vorkommens in der Anforderung genannten. Diese Klasse kann so einfach wie diese sein:

public class CustomerBecamePreferred : IDomainEvent
{ 
   public Customer Customer { get; set; }
} 

Die nächste Schritt ist haben die Möglichkeit für jede Klasse innerhalb unserer Domänenmodell, solche ein Ereignis auslösen, die problemlos mit der folgenden statische Klasse, macht Verwenden eines Containers wie Unity, Castle oder Spring.NET erfolgt:

public static class DomainEvents
{ 
   public IContainer Container { get; set; }
   public static void Raise<T>(T args) where T : IDomainEvent
   {
      foreach(var handler in Container.ResolveAll<Handles<T>>())
         handler.Handle(args);
   }
} 

Nun jede Klasse in unserer Domänenmodell kann ein Domäne-Ereignis, mit Entitätsklassen normalerweise Auslösen der Ereignisse auslösen wie folgt:

public class Customer
{ 
   public void DoSomething()
   {
      // regular logic (that also makes IsPreferred = true)
      DomainEvents.Raise(new CustomerBecamePreferred() { Customer = this });
   }
} 

Testbarkeit

Während die DomainEvents-Klasse dargestellt funktionsfähig ist, machen es Komponententests ein Domänenmodell etwas mühsam wie wir benötigen würden Sie verwenden eines Containers die Domäne überprüfen Ereignisse ausgelöst wurden. Einige Ergänzungen der DomainEvents-Klasse können das Problem, sidestep, wie in Abbildung 1 dargestellt.

Abbildung 1 Hinzufügungen zu der DomainEvents-Klasse

public static class DomainEvents
{ 
    [ThreadStatic] //so that each thread has its own callbacks
    private static List<Delegate> actions;

    public IContainer Container { get; set; } //as before

    //Registers a callback for the given domain event
    public static void Register<T>(Action<T> callback) where T : IDomainEvent
    {
       if (actions == null)
          actions = new List<Delegate>();

       actions.Add(callback);
   }

   //Clears callbacks passed to Register on the current thread
   public static void ClearCallbacks ()
   {
       actions = null;
   }

   //Raises the given domain event
   public static void Raise<T>(T args) where T : IDomainEvent
   {
      foreach(var handler in Container.ResolveAll<Handles<T>>())
         handler.Handle(args);

      if (actions != null)
          foreach (var action in actions)
              if (action is Action<T>)
                  ((Action<T>)action)(args);
   }
} 

Jetzt möglich ein Komponententest völlig eigenständig ohne einen Container als Abbildung 2 Zeigt.

Abbildung 2 Komponententests ohne Container

   public class UnitTest
   {
        public void DoSomethingShouldMakeCustomerPreferred()
        {
            var c = new Customer();
            Customer preferred = null;

            DomainEvents.Register<CustomerBecamePreferred>(
                p => preferred = p.Customer
                    );

            c.DoSomething();
            Assert(preferred == c && c.IsPreferred);
        }
   }

Befehle und Abfragen

Die Anwendungsfälle, die wir bisher überprüft worden haben, haben alle behandelt Ändern von Daten und die Regeln herum. Noch in vielen Systemen müssen Benutzer auch diese Daten anzeigen, sowie alle Arten von Suchvorgängen, Sortierungen und Filter ausführen können.

Ursprünglich hatte ich dachte, dass dieselben Entitätsklassen, die in das Domänenmodell waren zum Anzeigen von Daten an den Benutzer verwendet werden soll. Im Laufe der Jahre haben wurde abrufen zum verwendet verstehen, meine ursprüngliche denken häufig, falsche herausstellt. Das Domänenmodell ist alles Kapseln von Daten mit Unternehmen Verhalten.

Anzeigen von Benutzerinformationen beinhaltet kein Verhalten Business und alle zum Öffnen Sie die Daten ist. Auch wenn wir bestimmte sicherheitsrelevante Anforderungen um die Benutzer Informationen anzeigen können, kann, die häufig dargestellt werden, eine obligatorische Filterung der Daten.

Während ich "erfolgreich" in der Vergangenheit war erstellen Sie ein einzelnes permanente Objektmodell, das Befehle und Abfragen verarbeitet, war es oft sehr schwierig, skalieren, wie jeder Teil des Systems das Modell in eine andere Richtung tugged.

Wie sich herausstellt, dass Entwickler oft mehr anstrengenden Anforderungen nehmen als tatsächlich Geschäftsanforderungen. Die Entscheidung mit die Domäne Modell Entitäten, zum Anzeigen von Informationen für den Benutzer ist nur ein Beispiel.

Sie finden in einem Mehrbenutzersystem Änderungen durch einen Benutzer nicht unbedingt sofort für alle anderen Benutzer sichtbar sein müssen. Wir alle implizit verstehen dies beim Zwischenspeichern zur Leistungssteigerung Einführung – die tieferen Fragen bleiben jedoch: Wenn Sie die aktuellsten Daten warum gehen über das Domänenmodell benötigen, die unbedingt auf die Daten funktioniert? Wenn Sie nicht gefunden das Verhalten auf diese Domäne Modell Klassen, warum Sie Ihre Daten erhalten plough?

Für diese alten genug an Denken Sie daran dass, die Empfehlungen, um die Verwendung von COM+ geleitet uns so erstellen Sie separate Komponenten für Lesen - nur und für die Lese-/ Schreibzugriff Logik. Hier werden, einem Jahrzehnt zu einem späteren Zeitpunkt mit neuen Technologien wie das Entity Framework noch die gleichen Prinzipien halten weiter.

Abrufen von Daten aus einer Datenbank und einem Benutzer angezeigt ist recht trivial Problem lösen diese Tage. Dies kann so einfach wie mit einem Datenleser ADO.NET oder Datengruppe sein.

Abbildung 3 Zeigt, wie unsere "neu"-Architektur aussehen könnte.

fig03.gif

Abbildung 3- Modell für die erste Daten aus einer Datenbank

Eine Sache, die sich in diesem Modell von allgemeine Ansätze basierend auf bidirektionale Datenbindung unterscheidet ist, dass die Struktur, die mit die Daten verwendet wird für Änderungen verwendet nicht ist. Auf diese Weise z. B. Verfolgen von Änderungen nicht vollständig erforderlich.

In dieser Architektur bis Datenflüsse vom Benutzer die rechte Seite aus der Datenbank in das Formular von Abfragen und entlang der linken Seite an den Benutzer zurück an die Datenbank in Form von Befehlen an. Um eine vollständig separate Datenbank für diese Abfragen verwendete wechseln ist eine überzeugende Option hinsichtlich der Leistung und Skalierbarkeit, wie Lesevorgänge nicht Schreibvorgänge in die Datenbank störend (z. B. welche Seiten von Daten im Speicher in der Datenbank gespeichert sind), aber ein Mechanismus explizite Synchronisierung zwischen den beiden erforderlich ist. Optionen für diesen gehören ADO.NET Sync Services, SQL Server Integration Services (SSIS) und publish/subscribe messaging. Eine der folgenden Optionen auswählen, wird der Rahmen dieses Artikels sprengen.

Beibehalten des Business in der Domäne

Eine der Herausforderungen für Entwickler beim Entwerfen eines Domänenmodells ist wie Sie sicherstellen, dass Geschäftslogik außerhalb des Domänenmodells Beschnittzugaben nicht. Es ist keine Patentlösung dazu, aber eine Formatvorlage der Arbeit verwalten suchen einen Vorlieben Kompromiss zwischen Parallelität, Richtigkeit und Domäne-Kapselung, die auch für statische Analyse-Tools wie FxCop getestet werden können.

Hier ist ein Beispiel für die Art von Code finden Sie unter Interaktion mit einem Domänenmodell würde nicht soll:

public void SubmitOrder(OrderData data)
{ 
   var customer = GetCustomer(data.CustomerId);
   var shoppingCart = GetShoppingCart(data.CartId);
   if (customer.UnpaidOrdersAmount + shoppingCart.Total > Max)
      // fail (no discussion of exceptions vs returns codes here)
   else
      customer.Purchase(shoppingCart);
} 

Obwohl dieser Code ziemlich objektorientierte ist, können wir sehen, dass eine bestimmte Menge an Geschäftslogik hier statt in das Domänenmodell durchgeführt wird. Ein vorzuziehen Ansatz wäre dies:

public void SubmitOrder(OrderData data)
{ 
   var customer = GetCustomer(data.CustomerId);
   var shoppingCart = GetShoppingCart(data.CartId);
   customer.Purchase(shoppingCart);
} 

Im Fall von der neuen Reihenfolge überschreitet das Limit von unbezahlten Bestellungen würde, die von einem Domäne-Ereignis, durch eine separate Klasse behandelt, wie zuvor gezeigt dargestellt werden. Einkauf-Methode würde nicht Datenänderungen in diesem Fall ein technisch erfolgreichen Transaktion ohne Auswirkung Unternehmen führt.

Wenn die Differenz zwischen zwei Codebeispiele zu prüfen, sehen Sie, dass nur eine einzelne Methode für das Domänenmodell unbedingt aufruft bedeutet, dass alle Geschäftslogik es gekapselt werden. Die mehr konzentrierten API des Domänenmodells häufig verbessert Weitere Testbarkeit.

Dies zwar ein gutes Schritt in die richtige Richtung, es einige Fragen Parallelität öffnen.

Parallelität

Sie finden in zwischen dem Zeitpunkt, erhalten wir den Kunden und die Uhrzeit, die wir Fragen, um die Bestellung auszuführen, eine andere Transaktion kann kommen ändern Sie den Debitor im derart, dass seine unbezahlten Bestellmenge aktualisiert wird. Die möglicherweise unsere Buchung der Einkaufsbestellung (basierend auf zuvor abgerufenen Daten), obwohl er mit dem aktualisierten Zustand entsprechen nicht durchführen.

Um dieses Problem zu lösen einfachsten für uns bewirken, dass den Kundendatensatz gesperrt werden, wenn wir ursprünglich lesen –, der angibt, einer Transaktionsisolationsstufe mindestens repeatable Read ausgeführt (oder serialisierbar – die Standardeinstellung) wie folgt:

public void SubmitOrder(OrderData data)
{ 
   using (var scope = new TransactionScope(
   TransactionScopeOption.Required, 
   new TransactionOptions() { IsolationLevel = IsolationLevel.RepeatableRead }
))
   {
      // regular code
   } 
}

Obwohl dies etwas teurer als der Read committed-Isolationsgrad Sperren haben einige Hochleistungs-Umgebungen auf ausgeglichen Leistung ähnliche Ebenen verwaltet werden kann, wenn Entitäten, die einen bestimmten Anwendungsfall beteiligt sorgfältig geladen sind und von indizierten Spalten verbunden sind. Dies ist häufig größtenteils vom viel einfacher applicative Codierung Modell, versetzt werden, da kein Code für identifizieren oder Auflösen von Parallelitätsproblemen erforderlich ist. Wenn eine separate Datenbank für die Abfrage mit Teile des Systems und alle Lesevorgänge aus der OLTP-Datenbank für das Domänenmodell übergeben werden, können Leistung und Skalierbarkeit mit lesen-Commit-basierte Lösungen fast identisch sein.

Eine umfassende Lösung suchen

Das Domänen Modell Muster ist tatsächlich ein leistungsfähiges Tool in die Hände von einem erfahrenen Handwerker. Wie viele andere Entwickler, das erste Mal, das ich von diesem Tool kommissioniert, ich es over-used und möglicherweise sogar haben missbraucht es mit weniger als kosmischen Ergebnissen. Beim Entwerfen eines Domänenmodells Zeit Weitere betrachten die Besonderheiten jumping direkt in die Entität Beziehungen zu modellieren, statt in verschiedenen Anwendungsfälle gefunden – besonders achten diese Beziehungen für die Zwecke der Anzeige der Benutzerdaten einrichten. Wird besser bedient mit einfach und unkompliziert Datenbank Abfragen mit möglicherweise eine dünne Schicht von Fassade darauf einigen Datenbankanbieter Unabhängigkeitstests.

Wenn Code außerhalb das Domänenmodell mit Interaktion betrachten, Suchen nach die agile "einfachste Sache, die möglicherweise konnte" – einen einzigen Methodenaufruf für ein einzelnes Objekt aus der Domäne auch in der Fall, wenn Sie bei mehreren Objekten arbeiten. Domäne Ereignisse können aus Ihrer Lösung für die Behandlung komplexer Aktivitäten und technologische Integrationen ohne jede Komplikationen runden helfen.

Wenn Sie diesen Pfad zu starten, es dauerte einige Zeit in Meine denken anpassen, aber die Vorteile jedes Muster wurden schnell spürbar. Beginn ich all diese Muster zusammen mit gefundenen eine umfassende Lösung auch den anspruchsvollsten Business Domänen während den Code in jedem Teil des Systems kleinen, gezielten und testbare bereitgestellt – alles, was ein Entwickler möchten konnte.

Zitierte

Fowler M. Patterns of Enterprise Application Architecture, (Addison Wesley, 2003).

Udi Dahan Als ein MVP, IASA Master Architect und Dr. erkannt. Dobb's SOA Experte ist Udi Dahan der Software-Simplist, unabhängiger Berater, Lautsprecher, Autor und Trainer High-End-Dienste in Enterprise dienstorientierte, skalierbare und sichere Architektur und Entwurf bereitstellen. Wenden Sie sich an Udi über seinen Blog unter UdiDahan.com.