Skip to main content

Prinzipien der Domain-Schicht

Lernziele

Nachdem Sie diese Lektion abgeschlossen haben, sind Sie in der Lage, die folgenden Aufgaben auszuführen:

  • Erklären der Ursprünge des Domain-Musters anhand von EAA-Mustern
  • Bestimmen, welche Art von Apex-Code in die Domain-Schicht gehört
  • Erläutern, wo die Domain-Schicht in Ihre Anwendungsarchitektur und die Plattform passt
  • Entwickeln einer Domain-Schicht, die den bewährten Vorgehensweisen der Plattform entspricht

Voraussetzungen

Willkommen! Grundlage dieses Moduls sind Prinzipien, die Sie im Modul Apex Enterprise Patterns: Service-Schicht kennengelernt haben, sowie die Schritte, die Sie bei den praktischen Aufgaben in Ihrem Trailhead Playground durchgeführt haben. In diesem Modul wird die Service-Schicht als Mittel zur Kapselung der Geschäftsprozesse Ihrer Anwendung behandelt, wobei der Schwerpunkt darauf liegt, wie Services in einer einheitlichen, sinnvollen Weise für andere Teile Ihrer Anwendung, wie Visualforce-Steuerfelder, Batch-Apex und öffentlich ausgerichtete APIs, zugänglich gemacht werden.

Wenn Sie das Modul Apex Enterprise Patterns: Service-Schicht noch nicht absolviert haben, sollten Sie es durcharbeiten, bevor Sie mit diesem Modul fortfahren.

Die Domain-Schicht

Domain (Software-Engineering) – "Eine Domain ist ein Problemfeld, das eine Reihe von allgemeinen Anforderungen, Terminologie und Funktionalität für ein Softwareprogramm definiert, das zur Lösung eines Problems im als Domain Engineering bezeichneten Bereich der Computerprogrammierung entwickelt wurde". – Wikipedia, Domain (Software-Engineering)

Bei Salesforce Platform Enterprise Patterns wird die Domain-Schicht durch die von Ihnen erstellten benutzerdefinierten Objekte definiert (Projekt, Rechnung usw.), wodurch Sie schnell die Datenspeicher Ihrer Anwendung anlegen können. Aber was ist mit dem Verhalten dieser Objekte, wie z. B. der Validierung, Berechnung und komplexen Manipulation von Daten? Verhalten kann in Salesforce sowohl deklarativ (Point-and-Click) sowie programmgesteuert mit Apex festgelegt werden. Diese Kombination wirkungsvoll einzusetzen ist das Rezept für erfolgreiche Anwendungsentwickler für die Plattform. Und, seien wir ehrlich, möchten wir nicht alle erfolgreiche Entwickler für die Plattform sein?

Domain-Muster

Wenn aufgrund der Komplexität bestimmter Verhaltensweisen bei Objekten innerhalb Ihrer Anwendung eine Apex-Codierung notwendig ist, sollten Sie bei der Codestrukturierung und -faktorisierung Techniken der objektorientierten Programmierung (OOP) und das Domain Model-Muster einsetzen.

Domain Model – "Ein Objektmodell der Domain, das sowohl Verhalten als auch Daten abbildet." "Im schlimmsten Fall ist die Geschäftslogik sehr komplex. Regeln und Logik beschreiben viele verschiedene Arten und Ausprägungen von Verhalten, und es genau diese Komplexität, für die Objekte konzipiert wurden." – Fowler, Martin

Wie die Service-Schicht bietet auch das Domain Model eine granularere Möglichkeit für die Codekapselung und Wiederverwendung innerhalb Ihrer Anwendung, wie beispielsweise komplexe Validierung, Standardwertaktivierung und andere Logik im Zusammenhang mit komplexen Berechnungen und Manipulation.

In dieser Einheit sehen wir uns das Domain Model-Muster aus einer Apex-spezifischen Perspektive an. Es enthält Richtlinien für die eindeutige Zuordnung von Code aus der Domain-Schicht zu jedem benutzerdefinierten Objekt, so dass Sie weiterhin eine effektive Schichtenzuordnung und Separation of Concerns (SOC) innerhalb Ihrer Anwendungscodebasis erreichen. Bevor wir uns ansehen, woraus eine Domain-Klasse besteht, wiederholen wir kurz, wo diese Klassen verwendet werden.

  • Apex-Auslöser: CRUD-Vorgänge (Create, Read, Update, Delete) einschließlich des Rückgängigmachens von Löschvorgängen werden für Ihre benutzerdefinierten Objekte durchgeführt, wenn Benutzer oder Tools über die standardmäßigen Salesforce-Benutzeroberflächen oder die APIs der Plattform interagieren. Die Vorgänge werden an den entsprechenden Domain-Klassencode weitergeleitet, der dem Objekt und Vorgang entspricht.
  • Apex-Services: Code der Service-Schicht sollte leicht zu erkennen sein und es erleichtern, Code für eines oder mehrere der Objekte wiederzuverwenden, mit denen jeder seiner Vorgänge über Domain-Klassen interagiert. Bei diesem Ansatz bleibt der Schwerpunkt des Codes in der Service-Schicht darauf, den durch den Code bereitgestellten Geschäftsprozess bzw. -aufgabe zu orchestrieren.

Die Apex Domain-Klasse wird vom Apex-Auslöserhandler und dem Aufruf der Apex-Service-Methode genutzt, die wir im Modul Apex Enterprise Patterns: Service-Schicht verwendet haben. In dieser Einheit wird erläutert, wie diese beiden Bereiche über eine Domain-Klasse bereitgestellte Logik gemeinsam nutzen können, und zwar entweder explizit durch Aufrufen der Klassenmethoden oder indirekt über eine Auslöser-Handler-Logik.

Diagramm zur gemeinsamen Nutzung von Domain-Logik

Wichtig: Denken Sie daran, dass Code in Bezug auf von Ihnen entwickelte Steuerfelder für Lightning-Webkomponenten, Visualforce-Steuerfelder, Batch-Apex und API-Klassen Funktionen verwenden sollte, die ausschließlich über Vorgänge der Service-Schicht zur Verfügung gestellt werden. In der Domain-Schicht geschriebener Code wird daher immer indirekt von Klassen für Service-Schicht-Clients aufgerufen. Code in der Domain-Schicht ist in der Regel ein Aspekt der internen Geschäftslogik Ihrer Anwendung.

Designüberlegungen

Die Domain-Schicht eröffnet Ihrer Anwendung OOP-Möglichkeiten innerhalb von Apex, hält sich dabei jedoch (zum Großteil durch Benennungskonvention) an die Domain-Bedingungen und -konzepte Ihrer Anwendung sowie die bewährten Verfahren der Plattform.

Bedenken Sie dabei folgende Designüberlegungen. 

Mit Trail Together einem Dozenten folgen

Möchten Sie bei diesem Schritt einem Experten folgen? Schauen Sie sich dieses Video an, das Teil der Reihe "Trail Together" ist.

Verwenden von Domain-Klassen in Services

Sehen wir uns den OpportunitiesService an, der im Modul Apex Enterprise Patterns: Service-Schicht vorgestellt wurde, um Teile des Verhaltens der applyDiscounts-Methode in einer Methode der Domain-Klasse nach weiter unter zu verschieben.

Der folgende Code zeigt eine neue Implementierung der Service-Methode applyDiscounts. Diese Version verwendet die neue Opportunities-Klasse, die wir bei dieser Einheit erstellen. Diese Klasse kapselt die Logik, die Rabattberechnungen mit ihrer eigenen applyDiscount-Methode durchführt.

public static void applyDiscounts(Set<Id> opportunityIds, Decimal discountPercentage) {
    // Unit of Work
    // …

    // Validate parameters
    // ...

    // Construct Opportunities domain class
    Opportunities opportunities =
        new Opportunities(
            [select Id,Amount, (select UnitPrice from OpportunityLineItems)
            from Opportunity where Id in :opportunityIds]);

    // Apply discount via domain class behavior
    opportunities.applyDiscount(discountPercentage, uow);

    // Commit updates to opportunities     
    uow.commitWork();                      
}

Verwenden von Domain-Klassen in Auslösern

Sehen wir uns noch einen anderen Einstiegspunkt an. Wie im Diagramm im Abschnitt "Domain-Muster" dargestellt, rufen Benutzer Apex-Auslöser über die Salesforce-Benutzeroberflächen oder Code auf, der die Datensätze über DML- oder Salesforce-APIs bearbeitet.

Angesichts der Bedeutung der Domain-Klasse hinsichtlich der Kapselung der gesamten Logik und des Verhaltens für ein bestimmtes Domain-Objekt, müssen wir sicherstellen, dass Apex-Auslöseraufrufe auch an die entsprechenden Klassenmethoden weitergeleitet werden.

Wie bei vielen neuen Mustern im Zusammenhang mit Apex-Apex-Auslösern empfiehlt es sich, die Logik im Auslöser minimal zu halten. Apex-Auslöser sind keine Klassen und bieten damit zu eingeschränkt Möglichkeiten für die Refaktorisierung von Code oder die Verwendung von OO-Prinzipen wie die Vererbung. Sie eignen sich noch nicht einmal für bedingt komplexe Logik.

Der folgende Apex-Auslösercode wird durch die Verwendung der Klasse fflib_SObjectDomain ermöglicht, die Teil der Open Source-Bibliothek Apex Enterprise Patterns ist. Diese Klasse bildet eine Basisklasse für alle Domain-Klassen in Ihrer Anwendung. Mehr dazu in der nächsten Einheit.

Die statische Methode fflib_SObjectDomain.triggerHandler stellt sicher, dass die anwendbare Methode in der Opportunities-Klasse durch Lesen der Auslöser-Kontextvariablen Trigger.isAfter, Trigger.isBefore, Trigger.isInsert, Trigger.new usw. des Systems aufgerufen wird. Der Code in Apex-Auslösern, die dieses Muster verwenden, ist absichtlich sehr einfach.

trigger OpportunitiesTrigger on Opportunity (
  after delete, after insert, after update, after undelete, before delete, before insert, before update) {
   // Creates Domain class instance and calls appropriate methods
   fflib_SObjectDomain.triggerHandler(Opportunities.class);
}

Die im obigen Code referenzierte Opportunities-Klasse enthält Methoden wie onBeforeInsert und onAfterUpdate, die das Verhalten dieses Objekts implementieren, wenn diese Vorgänge auftreten.

Ressourcen

Teilen Sie Ihr Trailhead-Feedback über die Salesforce-Hilfe.

Wir würden uns sehr freuen, von Ihren Erfahrungen mit Trailhead zu hören: Sie können jetzt jederzeit über die Salesforce-Hilfe auf das neue Feedback-Formular zugreifen.

Weitere Infos Weiter zu "Feedback teilen"