Sollten Schnittstellen Domänenobjekte kennen?

8

In meinem System habe ich zwei verschiedene Projekte, eines definiert seine Schnittstellen und ein anderes definiert seine Domänenobjekte. Bisher habe ich es geschafft, die Schnittstellendefinitionen unabhängig von den Domänenobjekten zu haben, aber ich habe jetzt das Bedürfnis, bestimmte Domänenobjekte entweder als Parameter der in den Interfaces definierten Methoden oder als Rückgabewerte solcher zu integrieren.

Sollte ich Widerstand leisten und versuchen, die Schnittstellen von den Domänenobjekten unabhängig zu halten, oder ist das ein unbegründetes Problem?

BEARBEITEN - nachdem ich die Frage gepostet habe, habe ich überlegt, eine Schnittstelle für jedes Domain-Objekt zu definieren, so können sie getrennt bleiben - weiß nicht, ob es übertrieben ist oder ob es der Preis ist, damit sie unabhängig bleiben.

EDIT # 2 - Ich wurde gebeten, ein Beispiel zu geben, also werde ich versuchen, es einfach zu halten. Ich habe einen Prozess, der Bildtransformation behandelt, und eines meiner Domänenobjekte ist eine Klasse, die Informationen wie Auflösung, Seitenliste, Hash usw. enthält. Lassen Sie es DocumentInfo heißen. Ich habe eine Klasse, die DocumentInfo verwendet, um Aktionen wie GeneratePdfFromTiff auszuführen; Ich hatte GeneratePdfFromTiff zuerst als eine Schnittstellenmethode von IImageHandler definiert, die dann von ImageHandler implementiert wird.

Das Problem ist - Einer der Parameter von GeneratePdfFromTiff ist DocumentInfo. Hier habe ich die auf der Interface-Ebene definierte Methode, die DocumentInfo zu kennen, die auf der Domain-Ebene definiert wurde. Das ist die Art von Abhängigkeit, um die ich mich Sorgen mache.

    
Otávio Décio 05.03.2010, 16:13
quelle

4 Antworten

3

Das ist eine schwierige Frage, ich werde es versuchen. +1 für die Frage.

Domain-Modelle sollten wissen, wie sie mit den inneren Mechanismen interagieren können, wenn sie es in der realen Welt tun, denke ich. Das hängt natürlich stark von Ihrem genauen Domänenmodell ab, weil verschiedene Modelle derselben Sache sehr unterschiedliche Darstellungen ergeben würden.

Das Problem mit den Schnittstellen für jede Domänenmodellklasse ist, dass Ihr Domänenmodell selbst genau wie die Schnittstellen bereits eine bestimmte Sicht auf die Realität darstellt. Eine Schnittstelle ist nur innerhalb dieser bestimmten Domäne gültig. Sie können nicht die gleiche ICar für Transportplanung, Haushaltseinkommen Rechner und Auto-Aerodynamik-Optimierung verwenden.

Daher bezweifle ich, dass es sehr nützlich ist, ihre Abhängigkeiten zu weit zu isolieren.

Soweit ich weiß, sind Interfaces meist (immer?) öffentlich, was zu Zugriffsfragen führt. Die Schnittstelle sollte keine Details zur Implementierung enthalten, aber die Klassen des Domänenmodells enthalten die eigentliche Implementierung. Anstatt "nur auf einen Wert zugreifen" zu müssen, müssten Sie also einen weiteren Abstraktionsmechanismus für jedes Detail erstellen. Sie können z. B. nicht auf eine ID, einen Benutzer usw. im System zugreifen. Sie benötigen einen abstrakten ID-Typ, einen ID-Provider usw. Ich glaube, dass dies in einem großen realen Modell äußerst umständlich sein könnte.

Bestimmte "natürliche Domänengrenzen" sollten natürlich immer noch isoliert sein. Wenn Sie einen sozialen Texteditor erstellen, sollten alle Domänenklassen, die auch in einem herkömmlichen Texteditor auftreten würden, vollständig von den mit dem sozialen Netzwerk verbundenen Elementen isoliert sein. Daher sollte der Texteditor nur ein IUser kennen. Aber ich denke, ich erzähle dir nichts Neues ...

Das ist nicht sehr befriedigend, fürchte ich, aber es scheint, dass es im Wesentlichen eine dünne Linie ist, um zu gehen.

    
mnemosyn 05.03.2010, 16:52
quelle
2

Ich würde die Interessen der Softwareingenieure im Auge behalten, die die Schnittstelle benutzen. Der Versuch, zu entkoppeln, kann den Code abstrakter und in der Regel schwieriger zu konsumieren machen. Das bedeutet, dass mehr Code geschrieben werden muss, um "Dinge erledigen zu lassen", und dieser Code erfordert mehr Aufwand beim Schreiben.

Pardoxally, wegen der Extrakomplexität, wird es auch schwieriger, Sachen zu ändern, weil mehr Codezeilen von der sichtbaren Schnittstelle Ihrer Domain abhängen. Dies ist das Gegenteil von dem, was Sie wahrscheinlich erreichen möchten, da die Entkopplung dazu beitragen soll, dass das System (unter anderem) leichter zu verstehen und zu warten ist.

Aber es hängt wirklich sehr davon ab, welche Arten Sie darstellen wollen und wem. Können Sie einige Beispiele geben?

    
user180326 05.03.2010 16:51
quelle
1

Sie müssen das tatsächlich tun. Wenn Ihr Domänenmodell auf die Schnittstellenbibliothek verweist, können Sie nicht auf das Domänenmodell von der Schnittstellenbibliothek verweisen, da dies eine zirkuläre Referenz erzeugen würde.

Auch wenn dies nicht der Fall ist, wird durch Referenzieren des Domänenmodells aus den Diensten eine harte Kopplung zwischen den Schnittstellen und dem Domänenmodell erstellt. Dies bedeutet, dass jeder, der die Schnittstellen implementiert oder referenziert, auch auf das Domänenmodell verweist. Das willst du vielleicht nicht.

Ich würde definitiv empfehlen, dass Sie Schnittstellen von den Domänenobjekten extrahieren, die Sie zusammen mit Ihren Schnittstellen verwenden möchten.

Wenn Sie bereits eine Klasse namens Foo haben, dann extrahieren Sie die Schnittstelle IFoo und verwenden Sie sie in Ihren anderen Schnittstellen:

%Vor%

Sobald Sie beginnen, Domänenobjekte als Schnittstellen zu verwenden, werden Sie feststellen, dass es möglicherweise mehr Stellen gibt, an denen Sie die konkrete Klasse durch die Schnittstelle ersetzen können. Jedes Mal, wenn Sie das tun, wird Ihr Code mehr lose gekoppelt , und das ist eine gute Sache. Es macht Ihren Code wartbarer und anpassungsfähiger für Veränderungen.

Denken Sie beim Extrahieren einer Schnittstelle daran, dass Sie eine tiefe Extraktion durchführen müssen.

Wenn Foo so aussieht

%Vor%

sollte die Schnittstelle so aussehen:

%Vor%

(Entschuldigung für den C # -Code, wenn Sie in einer anderen Sprache schreiben ...)

    
Mark Seemann 05.03.2010 16:53
quelle
1

Ich würde empfehlen, Interfaces für Domänenklassen zu definieren, die zwar Verhalten haben, aber nicht für einfache Containerklassen oder Werttypen.

Wenn GeneratePdfFromTiff nur DocumentInfo wie ein Parameterobjekt behandelt und Die Dokumentinformationsklasse hat keine Logik, sie sollte nur ein öffentlich zugänglicher Typ sein.

Wenn die Dokumenteninformationsklasse Berechnungen durchführt oder irgendetwas anderes interessant macht, lohnt es sich, eine Schnittstelle zu extrahieren. (Aus all den ausgezeichneten Gründen, die Mark in seiner Antwort erwähnt.)

    
Jeff Sternal 05.03.2010 17:13
quelle

Tags und Links