Wird mit einer Eins-zu-Eins-Schnittstellen mit Domain-Entitäten eine gute oder schlechte Praxis? Warum?

StackOverflow https://stackoverflow.com/questions/825919

Frage

Eine Sache, die ich in einigen DDD Enterprise-Anwendungen zu sehen, die ich arbeite, ist die Verwendung von Schnittstellen, die die Bereichseinheiten identisch sind, mit einer Eins-zu-Eins-Abbildung von Eigenschaften und Funktionen. Tatsächlich ein Domain-Objekt immer durch, es ist eine Eins-zu-Eins-Schnittstelle verwendet wird, und alle Domänen Einheiten haben eine Eins-zu-Eins-Schnittstelle in diesem Stil.

Zum Beispiel:

Domain-Objekt-Konto:

public class Account : IAccount
{
     public string Name {get;set;}
     //...some more fields that are also in IAccount
     public decimal Balance {get;set;}
}

Und es passende Schnittstelle

public interface IAccount
{
   string Name {get;set;}
   //... all the fields in Account
   decimal Balance {get;set;}
}

Aber in letzter Zeit habe ich immer mehr davon überzeugt werden, dass dies in der Tat ein Anti-Muster.
Ich lief es von einigen Architekten in der Open-Source-Gemeinschaft, und sie sagen, dass dies auf Design-Fehler oder Mängel basiert, irgendwo oben in der Kette des Designs.

So sage ich meinen Kollegen, dass sie aufhören sollten Schnittstellen für die Domain-Objekte zu erstellen. Da es keinen Zweck zu ihnen, und Sie müssen die Schnittstelle aktualisieren, wenn Sie die Domain-Entitäten aktualisieren.

Zuerst wurde der Anspruch geltend gemacht, dass diese Schnittstellen bieten ‚Entkopplung‘, aber ich entgegen, dass, weil die Schnittstellen haben eine Eins-zu-Eins-Beziehung mit den Domain-Entitäten, die sie wirklich eine Entkopplung nicht bieten, eine Änderung der Schnittstellenmittel eine Änderung in der Domäne Einheit und umgekehrt.

Die nächste Behauptung ist, dass wir die Schnittstellen zu Testzwecken benötigen. Mein Zähler ist, dass Rhino-Mocks für die spöttische und Anstoßen von konkreten Klassen zur Verfügung stellt. Aber sie behaupten, dass Rhino-Mocks Probleme mit konkreten Klassen hat. Ich weiß nicht, ob ich kaufe, dass, auch wenn Rhino-Mocks Probleme mit konkreten Klassen hat, das nicht unbedingt, dass wir Schnittstellen für die Domain-Entitäten verwendet werden sollen.

Also ich bin neugierig:

Warum würden Sie haben eine Eins-zu-Eins-Schnittstellen für Ihre Domain Entitäten?

Warum nicht?

Warum ist es eine gute oder schlechte Praxis?

Vielen Dank für das Lesen!

Bearbeiten : Ich sollte anmerken, dass ich Schnittstellen die ganze Zeit, und ich glaube, dass, wenn es heißt denn ich eine Schnittstelle am Tropfen eines Hutes verwenden. Aber ich beziehe mich speziell auf Domain-Entitäten mit einer Eins-zu-Eins-Schnittstellen.

War es hilfreich?

Lösung

Es ist eine schlechte Praxis, wie beschrieben, aber ...

Es gibt keinen bestimmten Grund, dass Ihre Schnittstellen benötigen, um Ihre Domain-Entitäten, anders zu sein als; manchmal ist es wirklich die richtige Zuordnung. Aber es ist verdächtig, dass es immer der Fall ist. Der Grund zur Sorge gibt es eine Frage, ob die Schnittstellen wirklich entworfen wurden, oder ob sie nur aus Mangel an Zeit / Faulheit in Platz geworfen.

Ihr Beispiel zu verwenden, die IAccount Schnittstelle, die Sie beschreiben, macht Getter und Setter auf dem Objekt Konto; es scheint ein wenig seltsam, und es ist unwahrscheinlich, dass alles, was einen Bedarf hat ein Konto verwendet das Guthaben auf dem Konto eingerichtet werden soll, und dass die implizite Genehmigung ist auf dieser Ebene der Schnittstelle angegeben. Gibt es keinen Platz in Ihrem System, wo Sie nur überprüfen wollen, aber nicht den Kontostand gesetzt?

Andere Tipps

Der größte Grund für immer die Domänenobjekte als Schnittstellen spezifiziert, anstatt direkt als Klassen ist, dass Sie ein gewisses Maß an Freiheit bei der Umsetzung zu geben. In Ihrem Beispiel haben Sie nur eine Art von IAccount, so ist es ein wenig redunant.

Aber was, wenn Sie hatten, zum Beispiel:

public class Account : IAccount { ... }       // Usual account, persistent
public class MockAccount : IAccount { ... }   // Test mock object
public class TransAccount : IAccount { ... }  // Account, not persistent
public class SimAccount : IAccount { ... }    // Account in a performance sim

und so weiter?

die Domänenobjekte als Schnittstellen Durch die Definition, können Sie die Implementierungen ersetzen, ohne Ihre Domain Definition zu stören.

In der Regel, wenn meine Klassen sind nicht Teil eines Designmusters wie Strategie oder Besucher sein werden ich nicht hinzufügen Schnittstellen.

Schnittstellen Hinzufügen ist wirklich nützlich für Design-Muster wie Strategie und Besucher, aber in den Fällen, ich Kohlenstoff die Getter und Setter der Domain-Klassen nicht kopieren. Stattdessen ich Schnittstellen erstellen, die für die Design-Muster-Schnittstellen spezifisch sind ich erstellen.

interface SomeStrategy {
   void doSomething(StrategyData data);
}

interface StrategyData {
   String getProperty1();

   String getProperty2();
} 

Das ermöglicht es mir, die Domain-Klassen implementieren diese Schnittstellen zu lassen, oder die Adapter-Muster zu verwenden. Ich finde, das ist ein viel sauberer Ansatz, der nur Schnittstellen zum Wohl es zu schaffen.

Das Design sollte immer Unsicherheit reduzieren. Erstellen von Schnittstellen aus Gründen der es nicht Unsicherheit nicht reduzieren, in der Tat erhöht es wahrscheinlich Verwirrung, da es keinen Sinn macht.

One-to-One-Schnittstellen auf Einheiten sind ein Anti-Muster

James Gregory legte es besser als ich hier .

Ich stimme Ihnen zu. Schnittstellen sollte als Vertrag handeln, so gibt es keinen Wert aus mit einer Eins-zu-Eins-Schnittstellen mit Domain-Entitäten. Es kann nützlich sein, wenn Sie zu abstrahieren einem bestimmten Verhalten mögen. Aber dies wird in bestimmten Fällen arbeiten.

Warum hat dieses verpufft?

Ich finde, eine Schnittstelle für ein Domain-Objekt ist, als Charlie Martin sagte, ermöglicht es mir, meine Implementierung zu wählen.

Ein grundsätzliches Beispiel ist die Kennung (object.Id) für ein Objekt, wird dies unterschiedlich sein, je nachdem, wo Sie das Objekt speichern und die Verantwortung für die Schaffung kann oder nicht später bei der Umsetzung der Daten ruhen. In SQL Server können Sie für einen Autowert gehen, aber in Azure-Tabellen-Speicher könnten Sie für eine Guid gehen, aber Sie wollen nicht auf die Geschäftslogik von Ihnen App ändern müssen, weil Sie ändern, wo Sie Ihre Daten speichern.

ich darf oder nicht wählen, um mein Domain-Objekt haben beharrte, oder sogar in der Präsentationsschicht verwenden - es auf dem Umfang meiner App abhängt, die am besten ist. Aber das Hinzufügen einer Reihe von gemeinsamen Domain-Schnittstellen in einer gemeinsamen Schicht ermöglicht es mir, Dienstleistungen gegen sie zu schreiben und wieder verwendet sie wieder und wieder.

Wir würden das gleiche Argument, gehen über das, was eine Adresse sein sollte, wenn wir nicht iAddress bekommen hatte, neue Programmierer Sachen für Kreditkarten Umschreiben werden würde, wenn es nicht für ICreditCard waren.

Das Anti-Muster Etikett eine schlechte Verwendung von Sprache ist, es ist eine starke Vereinfachung für die Beschreibung des Wertes von Lösungen für komplexe und abwechslungsreiche Aufgaben.

Es gibt einen Platz für die meisten Muster auch die geschmähte Singleton, was bedeutet, es ist nicht ein „anti-Muster“, zumindest so weit wie der Begriff schon sagt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top