Sagen wir, ich habe eine Car
Klasse:
public class Car
{
public string Engine { get; set; }
public string Seat { get; set; }
public string Tires { get; set; }
}
Nehmen wir an, wir erstellen ein System für einen Parkplatz. Ich werde einen Großteil der Car
Klasse verwenden, also CarCollection
erstellen wir eine Klasse. Möglicherweise gibt es einige zusätzliche Methoden wie FindCarByModel
:
public class CarCollection
{
public List<Car> Cars { get; set; }
public Car FindCarByModel(string model)
{
// code here
return new Car();
}
}
Wenn ich eine Klasse mache ParkingLot
, was ist die beste Übung?
Option 1:
public class ParkingLot
{
public List<Car> Cars { get; set; }
//some other properties
}
Option 2:
public class ParkingLot
{
public CarCollection Cars { get; set; }
//some other properties
}
Ist es überhaupt eine gute Praxis, ein ClassCollection
anderes zu erschaffen Class
?
CarCollection
eher an einem vorbei gehen als an einemList<Car>
herum? Vor allem, weil CarCollection die Backing-List-Klasse nicht erweitert oder sogar die Collection-Schnittstelle implementiert (ich bin mir sicher, dass C # ähnliche Dinge hat).public class CarCollection
nicht implementiert IList oder ICollection, etc ... so kann man es nicht etwas übergeben , die mit einer Liste in Ordnung ist. Es behauptet als Teil seines Namens, dass es eine Sammlung ist, implementiert aber keine dieser Methoden.CarColection
mit einerTotalTradeValue
Eigenschaft darauf. DDD ist nicht die einzige Möglichkeit, Systeme zu entwerfen, sondern weist lediglich darauf hin, dass dies eine Option ist.Antworten:
Vor Generics in .NET war es üblich, typisierte Sammlungen zu erstellen, sodass Sie
class CarCollection
für jeden Typ, den Sie gruppieren mussten, usw. haben . In .NET 2.0 wurde mit der Einführung von Generics eine neue KlasseList<T>
eingeführt, die es Ihnen erspart, soCarCollection
viel wie möglich zu erstellenList<Car>
.Meistens werden Sie feststellen, dass dies
List<T>
für Ihre Zwecke ausreicht. Es kann jedoch vorkommen, dass Sie ein bestimmtes Verhalten in Ihrer Sammlung wünschen. Wenn Sie dies für richtig halten, haben Sie mehrere Möglichkeiten:List<T>
beispielsweise kapseltpublic class CarCollection { private List<Car> cars = new List<Car>(); public void Add(Car car) { this.cars.Add(car); }}
public class CarCollection : CollectionBase<Car> {}
Wenn Sie sich für den Einkapselungsansatz entscheiden, sollten Sie den Enumerator mindestens verfügbar machen, damit Sie ihn wie folgt deklarieren:
Ohne das können Sie
foreach
die Sammlung nicht überschreiben .Einige Gründe, warum Sie eine benutzerdefinierte Sammlung erstellen möchten, sind:
IList<T>
oder vollständig verfügbar machenICollection<T>
Ist es eine gute Übung? Nun, das hängt davon ab, warum Sie es tun. Wenn es zum Beispiel einer der Gründe ist, die ich oben aufgeführt habe, dann ja.
Microsoft macht das ziemlich regelmäßig, hier sind einige relativ neue Beispiele:
Was Ihre
FindBy
Methoden betrifft, wäre ich versucht, sie in Erweiterungsmethoden zu setzen, damit sie für jede Sammlung verwendet werden können, die Autos enthält:Dies trennt das Anliegen, die Sammlung abzufragen, von der Klasse, in der die Autos gespeichert sind.
quelle
ClassCollection
Methoden zum Hinzufügen, Löschen und Aktualisieren verwerfen , indem ich eine neue hinzufüge,CarCRUD
die alle diese Methoden zusammenfasst ...CarCRUD
Erweiterung nicht empfehlen, da die Durchsetzung ihrer Verwendung schwierig wäre. Der Vorteil beim Einfügen der benutzerdefinierten Crud-Logik in die Auflistungsklasse besteht darin, dass sie nicht umgangen werden kann. Darüber hinaus interessiert Sie die Suchlogik in der Core-Assembly, in derCar
etc deklariert ist, möglicherweise nicht wirklich. Dies ist möglicherweise nur eine Aktivität der Benutzeroberfläche.Nein. Die Erstellung von
XXXCollection
Klassen geriet mit dem Aufkommen von Generika in .NET 2.0 fast aus der Mode. Tatsächlich gibt es die raffinierteCast<T>()
LINQ-Erweiterung, mit der Leute heutzutage Dinge aus diesen benutzerdefinierten Formaten herausholen.quelle
ClassCollection
? Ist es eine gute Praxis, sie auf die Hauptleitung zu setzenClass
?FindCarByModel
Methode sprechen , ist dies als Methode in Ihrem Repository sinnvoll, die etwas komplexer ist als nur eineCar
Sammlung.Wie im obigen FindByCarModel-Beispiel ist es häufig praktisch, domänenorientierte Methoden zum Suchen / Teilen von Sammlungen zu verwenden, aber es ist nicht erforderlich, Wrapper-Auflistungsklassen zu erstellen. In dieser Situation erstelle ich jetzt in der Regel eine Reihe von Erweiterungsmethoden.
Sie fügen Sie so viele Filter oder Utility - Methoden dieser Klasse , wie Sie wollen, und Sie können sie überall nutzen zu können muss
IEnumerable<Car>
, die alles enthältICollection<Car>
, Anordnungen vonCar
,IList<Car>
usw.Da unsere Persistenzlösung über einen LINQ-Anbieter verfügt, werde ich häufig auch ähnliche Filtermethoden erstellen, die auf
IQueryable<T>
das Repository angewendet und zurückgegeben werden , damit wir diese Vorgänge auch auf das Repository anwenden können.Die Sprache von .NET (naja, C #) hat sich seit 1.1 sehr verändert. Das Verwalten von benutzerdefinierten Auflistungsklassen ist mühsam.
CollectionBase<T>
Wenn Sie nur domänenspezifische Filter- und Auswahlmethoden benötigen, können Sie mit der Erweiterungsmethodenlösung nur wenig von der Vererbung profitieren.quelle
Ich denke, dass der einzige Grund, eine spezielle Klasse für das Speichern einer Sammlung anderer Elemente zu erstellen, darin bestehen sollte, etwas Wertvolles hinzuzufügen, etwas mehr als nur eine Instanz
IList
einer Sammlung oder eine andere Art von Sammlung zu kapseln / zu erben .Beispiel: Fügen Sie in Ihrem Fall eine Funktion hinzu, die Unterlisten von Autos zurückgibt, die auf geraden / ungeraden Stellplätzen geparkt sind. Und selbst dann. Vielleicht nur, wenn sie häufig wiederverwendet werden, weil sie nur eine Zeile mit einem netten LinQ benötigt Funktion und wird nur einmal verwendet, was ist der Sinn? KUSS !
Wenn Sie viele Sortier- / Suchmethoden anbieten möchten, dann denke ich, dass dies nützlich sein könnte, da sie in diese spezielle Sammlungsklasse gehören sollten. Dies ist auch ein guter Weg, um die Komplexität einiger Suchanfragen zu "verbergen" oder was auch immer Sie in einer Sortier- / Suchmethode tun könnten.
quelle
Class
Ich bevorzuge die folgende Option, damit Sie Ihre Methode zur Sammlung hinzufügen und den Vorteil von list nutzen können.
und dann können Sie es wie C # 7.0 verwenden
Oder du kannst es gerne benutzen
- Allgemeine Version dank @Bryan Kommentar
und dann kannst du es benutzen
quelle