it-swarm.com.de

Soll ich Schnittstellen für Datenübertragungsobjekte erstellen?

Ist es eine gute oder eine schlechte Idee, eine Schnittstelle für Datenübertragungsobjekte zu erstellen? Vorausgesetzt, das Objekt ist normalerweise veränderlich.

Obwohl mein Beispiel in Java ist, sollte es auf jede andere Sprache anwendbar sein, die ähnliche Konzepte hat.

interface DataTransferObject  {
    String getName();
    void setName(String name);
}

class RealDataTransferObject  implements DataTransferObject {

    String name;
    String getName() {
        return name;
    } 
    void setName(String name) {
        this.name = name;
    }
}

Dies ist natürlich ein vereinfachtes Beispiel. Im wirklichen Leben kann es mehr Felder geben.

20

Die allgemeine Antwort lautet nein , da Sie niemals Code hinzufügen sollten, ohne einen bestimmten, konkreten Grund dafür zu haben, und es gibt keinen allgemeinen Grund für eine solche Schnittstelle .

Davon abgesehen kann es manchmal einen guten Grund geben. Aber in allen Fällen, die ich gesehen habe, waren diese Schnittstellen teilweise und deckten nur eine oder einige Eigenschaften ab, die von mehreren Klassen geteilt wurden, die ich polymporphisch verwenden wollte, ohne ihnen eine gemeinsame Oberklasse zu geben. Typische Kandidaten sind eine Id -Eigenschaft, die in einer Art Registrierung verwendet werden soll, oder eine Name -Eigenschaft, die dem Benutzer angezeigt werden soll. Es kann jedoch in jedem Fall nützlich sein, in dem Code alles verarbeiten soll, was ein X enthält. Erstellen Sie einfach eine XSource -Schnittstelle, die das getX enthält (und nur bei Bedarf das setX) Methoden.

Aber eine separate Schnittstelle für jede Modellklasse, die alle Eigenschaften enthält? Ich kann mir keinen guten Grund dafür vorstellen. Ein schlechter Grund wäre ein schlecht gestalteter Rahmen, der dies erfordert. Entity EJBs haben genau das getan, wenn ich mich richtig erinnere. Zum Glück waren sie so schlecht, dass sie nie viel Traktion gewonnen haben und seit EJB 3.0 veraltet sind

Nebenbemerkung: Bitte vermeiden Sie die Verwendung des Begriffs "Wertobjekt", um Java Beans mit nur trivialen Gettern und Setzern - dies widerspricht der allgemeineren Definition von Wertobjekt als etwas ohne Identität, die normalerweise unveränderlich ist. Ein besserer Begriff wäre DTO oder Modellklasse - obwohl im letzteren Fall zu beachten ist, dass anämische Domänenmodelle gelten als Antimuster.

24

Das Erstellen einer Benutzeroberfläche ist in Ordnung, aber NICHT so, wie Ihr Beispiel funktioniert. Sie sollten den Setter von der Schnittstelle entfernen, und es wird in Ordnung sein:

interface ValueObject {
  String getName();
};

Dies ermöglicht viele verschiedene Implementierungen davon, wie der Name aus der Datenbank abgerufen werden kann ... Setter sollte sich in einer anderen Schnittstelle befinden.

2
tp1

Schnittstellen definieren einen Vertrag zwischen den Klassen, die die Schnittstellen implementieren, und ihren Clients. Sie werden als Abstraktionsmechanismus verwendet, damit Clients "Dinge mit einem bestimmten Verhalten" manipulieren können.

Die allgemeine Antwort auf die Frage "Soll ich diese Schnittstelle erstellen und verwenden?" ist: Ja, wenn Sie ein (ein einziges) Konzept zuordnen können, das für Ihre Kunden semantisch relevant ist.

Zum Beispiel ist Vergleichbar eine gute Schnittstelle, weil es erklärt, dass Dinge dank einer ihrer Methoden verglichen werden können, und als Kunde bin ich daran interessiert, mit vergleichbaren Objekten umzugehen (z. B. um sie zu sortieren). . Ein Gegenteil, CoolStuff ist keine gute Schnittstelle, wenn Sie zugeben, dass die coolen Objekte kein bestimmtes Verhalten haben (tatsächlich können Sie sich eine Software vorstellen, in der der Umgang mit coolen Objekten sinnvoll ist, weil sie es haben ein häufiges Verhalten wie eine beCool Methode).

In Ihrem speziellen Fall glaube ich, dass Ihre Schnittstelle nutzlos ist. Wer wird es wie und wann verwenden? Sie können nicht für jeden der veränderlichen Werte eine Schnittstelle erstellen. Fragen Sie sich also, welche relevante und interessante Eigenschaft hinter Ihren Methoden steckt.

Wenn Sie sich mit Objekten befassen möchten, auf deren veränderbare Werte über verschiedene Methoden zugegriffen werden kann, lesen Sie den Begriff Java bean) und die Art und Weise, wie Sie Ihre Klassen zwingen können, ihre Konventionen zu übernehmen .

2
mgoeminne

Wie Michael sagte, fügen Sie keine Schnittstelle hinzu, es sei denn, Sie haben einen bestimmten Bedarf dafür.

Testen ist ein Beispiel für einen guten Grund. Obwohl ich es vorziehe, echte Kollaborateure zu verwenden, wenn sie nur "Wertobjekte" sind, wie Sie sie nennen, müssen Sie für eine echte Isolation von Komponententests möglicherweise ein gefälschtes Objekt zum Testen erstellen. In diesem Fall ist eine Schnittstelle sehr hilfreich.

2
jhewlett

Wenn Sie möchten, dass dieses Objekt in Zukunft eine Art Feldvalidierung erhält, sollten Sie diese frühzeitig einkapseln.

1
goodfella

Die 'Schnittstelle für Wertobjekt' wird verwendet, um einen Accessor aufzurufen.

Ich habe verschiedene Richtlinien bezüglich der Bedürfnisse von Accessoren erlebt. Einige Leute befürworten, wenn so viel wie möglich, andere verbieten dann, die Menge des zu schreibenden Codes zu reduzieren.

Einige Rationale für Accessoren (oder direkte Wertverwendung) sind die folgenden:

  • Mit Accessors können Sie später ändern, wie der Wert gespeichert wird
  • Accessors ermöglicht das Hinzufügen eines Zugriffsprotokolls, wenn Sie Ihre Software debuggen möchten (wenn Sie einen Protokollaufruf in einer einzelnen Methode hinzufügen, erfassen Sie jede Wertänderung).
  • Accessoren entsprechen eher der Objektprogrammierung, wobei jede Variable durch Methoden gekapselt wird
  • Accessors reduzieren die Ausdruckskraft des Codes (mehr SLOC für das gleiche Ergebnis)
  • Accessors benötigt etwas CPU

Ich persönlich befürworte, die Anzahl der Accessoren zu reduzieren und sie zu verwenden, wenn Sie erwarten, dass der Setter (setName) später mehr als eine einfache Auswirkung wird.

Diese Art von Wertobjekt ist ziemlich niedrig. Ich würde vorschlagen, es in eine von zwei Richtungen zu verschieben: (1) das Wertobjekt unveränderlich machen, dh wie ein realer Wert, oder (2) die Veränderlichkeit auf eine übergeordnete domänenorientierte Ebene erhöhen Geschäftsfunktion, dh wir sollten Schnittstellen in Bezug auf domänenrelevante Funktionseinheiten offenlegen.

0
Erik Eidt