Datenzugriffsschicht: Exposed List <>: schlechte Idee?

Ich bin gerade dabei, eine einfache Datenzugriffsschicht zu codieren, und ich fragte mich, welcher Typ ich den anderen Schichten aussetzen sollte.

I am going to internally implement the Data as a List<>, but I remember reading something about not exposing the List type to the consumers if not needed.

public List GetAllUsers()//non C# users: that means List of User :)

Weißt du warum (Google hat nicht geholfen)? Was entlarvst du normalerweise für solche Sachen? IList? IEnumerierbar?

3

3 Antworten

Usually it's best to expose the least powerful interface that the user can still meaningfully work with. If the user just needs some enumerable data, return IEnumerable. If that's not enough because the user needs to be able to modify the list (attention! shouldn't often be the case), return an IList.

/BEARBEITEN:

Joel stellt in seinem Kommentar eine gültige Frage: Warum in der Tat die schwächste Schnittstelle offenlegen, anstatt dem Benutzer maximale Power zu geben? (umschrieben)

Die Idee dahinter ist, dass die Methode, die die Daten zurückgibt, möglicherweise nicht erwartet, dass der Benutzer seinen Inhalt ändert: Eine andere Methode der Klasse erwartet möglicherweise weiterhin, dass die Liste nicht leer ist, nachdem eine Referenz darauf zurückgegeben wurde. Stellen Sie sich vor, der Benutzer entfernt alle Daten aus der Liste. Die andere Methode muss nun eine zusätzliche Überprüfung vornehmen, ob el möglicherweise nicht notwendig war.

Noch wichtiger ist, dass dadurch Teile der internen Implementierung durch den Rückgabetyp verfügbar gemacht werden. Wenn ich die Implementierung in Zukunft so ändern muss, dass sie keinen Container IList mehr verwendet, habe ich ein Problem: Ich muss entweder den Methodenvertrag ändern und eine build-breaking-Änderung einführen. Oder ich muss die Daten in einen Listencontainer kopieren.

Stellen Sie sich beispielsweise vor, dass eine effiziente Implementierung ein Dictionary verwendet und nur die Auflistung Werte zurückgibt, die IList nicht implementiert.

6
hinzugefügt
Sie haben auch die Möglichkeit, ReadOnlyCollection zurückzugeben, wenn Sie dies auf der Angerufenen Seite steuern möchten.
hinzugefügt der Autor CVertex, Quelle
Ich habe die Idee des "schwächsten" noch nicht gekauft; Wie wäre es, jeden Code so nützlich wie möglich zu machen?
hinzugefügt der Autor Joel Coehoorn, Quelle

Definitiv ein ISomething. Durch die Verwendung einer Schnittstelle wird die Kopplung reduziert und die Details der Implementierung der Datenschicht können später einfacher geändert werden. Welche Schnittstelle hängt von den Umständen ab. IList ist gut, aber manchmal benötigen Sie möglicherweise ICollection-Funktionalität oder möchten Werte angeben, die ReadOnly sind.

3
hinzugefügt

Sie sollten sorgfältig überlegen, bevor Sie IEnumerable zurückgeben. Wenn der zugrunde liegende Code "yield" verwendet, um IEnumerable zu generieren, oder LINQ verwendet, werden Sie alle Ressourcen, die verwendet werden, offen halten.

Sie sollten das IEnumerable in ein anderes IEnumerable kopieren, bevor Sie es zurückgeben. Mit IList machen Sie dies zu einer Voraussetzung, damit niemand versehentlich IEnumerable zurückgeben kann.

Auf der anderen Seite bedeutet das Zurückgeben einer IList für den Aufrufer, dass sie die zurückgegebene Liste ändern können.

2
hinzugefügt
Guter Punkt. Vielleicht könnten Sie ein Beispiel hinzufügen, das einen solchen Fall der Vollständigkeit halber darstellt.
hinzugefügt der Autor Konrad Rudolph, Quelle