Domänendienste als Fassaden

8

Ich habe .NET Domain-Driven Design mit C # gelesen : Problem - Design - Lösung und festgestellt, dass der Autor für jeden Aggregatstamm einen Domänendienst erstellt hat.

Die Domänendienste waren jedoch nur Fassaden des entsprechenden Repositorys. Zum Beispiel ist dies ein Codebeispiel aus der Anwendung aus seinem Buch

public static class CompanyService
{
    private static ICompanyRepository repository;
    private static IUnitOfWork unitOfWork;

    static CompanyService()
    {
        CompanyService.unitOfWork = new UnitOfWork();
        CompanyService.repository = 
            RepositoryFactory.GetRepository<ICompanyRepository, 
            Company>(CompanyService.unitOfWork);
    }

    public static IList<Company> GetOwners()
    {
        return CompanyService.GetAllCompanies();
    }

    public static IList<Company> GetAllCompanies()
    {
        return CompanyService.repository.FindAll();
    }

    public static void SaveCompany(Company company)
    {
        CompanyService.repository[company.Key] = company;
        CompanyService.unitOfWork.Commit();
    }

    public static Company GetCompany(object companyKey)
    {
        return CompanyService.repository.FindBy(companyKey);
    }
}

Wie Sie sehen, sind fast alle Aufrufe der Dienste Wrapper für Repository-Aufrufe. Ist dies ein gutes Muster beim Aufbau von Domänendiensten?

Sollten wir unsere Repositorys immer in Domänendienste verpacken? Gibt es einen besseren Ansatz?

Songo
quelle
Was meinst du mit "besser"?
Robert Harvey
Die Frage, die ich mir hier stellen würde, lautet: "Welchen Wert bietet der CompanyService gegenüber dem CompanyRepository?". Wenn die Antwort keine ist, ist die Klasse ein Mittelsmann - löschen Sie sie gnadenlos!
MattDavey
@ MattDavey gut in diesem Codebeispiel kann ich sehen, dass die Repository-Methoden in Domänenaufrufe übersetzt wurden. Zum Beispiel GetAllCompanies()Wraps repository.FindAll(). Warum kann ich nicht repository.GetAllCompanies()stattdessen einfach eine Repository-Methode erstellen ?!
Songo
@Songo: Hängt davon ab, ob jede andere Methode in Ihrer Service-Schicht einen Repository-Methodenaufruf auf ähnliche Weise umschließt.
Robert Harvey

Antworten:

7

Ein Repository ist als Abstraktion für Ihren Datenspeicher gedacht und bietet im Allgemeinen Funktionen zum Abrufen von Daten. Mit dieser Anordnung können Sie beispielsweise den Datenspeicher für einen anderen Datenspeicher ändern (z. B. von Oracle zu SQL Server, obwohl dies in der Praxis selten vorkommt), und Ihre Repository-API sollte weiterhin funktionieren, wenn Sie keine verfügbar gemacht haben implementierungsspezifische Details.

Eine Serviceschicht hingegen ist eine API, die von einem externen Benutzer oder Agenten verwendet werden soll und Dienste bereitstellt , nicht das Abrufen von Daten an sich (obwohl dies möglich ist ). Eine Service-API kann auf mehrere Repositorys zurückgreifen und Transformationen für die Daten durchführen, bevor sie dem Client bereitgestellt werden. Möglicherweise werden die Daten in benutzerdefinierte Objekte eingeschlossen oder Paging-Funktionen bereitgestellt. Sie können in Ihrer Service-Schicht Dinge tun, die über das einfache Speichern und Abrufen von Daten hinausgehen.

Wenn Sie keine zusätzliche Abstraktionsebene bereitstellen müssen, die über das Repository hinausgeht, benötigen Sie möglicherweise überhaupt keine Serviceschicht.

Robert Harvey
quelle
1
+1 Eine Sache hat meine Aufmerksamkeit in dem Code erregt, den ich gepostet habe. DasSaveCompany Methode markiert die Arbeitseinheit. Wenn ich ausschließlich ein Repository verwenden würde, würde sich der Aufruf zum Festschreiben aller Änderungen im Repository befinden?
Songo
Ja, es würde ...
Robert Harvey
2

Wenn Ihre Anwendung wächst, gibt es komplexe Vorgänge, die Ihre Service-Schicht umschließen und verfügbar machen kann. Es ist wirklich eine Fassade über dem Domain-Modell. Beispielsweise interessiert Sie in einer Verkaufs-App die Werbebuchung möglicherweise nicht als diskretes Objekt innerhalb des Modells. Sie möchten nur Artikel zu einem Warenkorb hinzufügen, sie auschecken und eine Rechnung für den Benutzer drucken, nachdem Rabatte angewendet wurden.

Hinter den Kulissen sind wahrscheinlich Dutzende von Objekten an der Interaktion beteiligt. Der Dienst projiziert möglicherweise eine reduzierte Ansicht des Objektmodells, sodass der Client von diesen Änderungen nicht betroffen ist, wenn sich das Domänenmodell hinter den Kulissen ändert.

Michael Brown
quelle