Wann sollten Sie den Datentyp Schlüssel / Wert in eine eigene Klasse einfügen, anstatt eine vordefinierte generische Struktur wie a KeyValuePair
oder a zu verwenden Tuple
?
Beispielsweise enthalten die meisten von mir erstellten Kombinationsfelder einen Anzeigenamen und einen Wert. Dies ist die Art von Daten, die ich zu entscheiden versuche, wann eine neue Klasse eingefügt werden soll und wann nur ein KeyValuePair verwendet werden soll.
Zur Zeit arbeite ich an etwas , dass Anwendungen iCalendar
und die ausgewählten Benutzerdaten werden schließlich zu einem kombinierten key1=value1;key2=value2;
Art von String. Ich begann damit, die Daten in ein KeyValuePair<string,string>
einzutragen, aber jetzt frage ich mich, ob das stattdessen eine eigene Klasse sein sollte.
Insgesamt bin ich daran interessiert herauszufinden, welche Richtlinien verwendet werden, wenn eine vorhandene Struktur / Klasse wie ein KeyValuePair
Objekt mit mehr als 2 Eigenschaften verwendet wird, und in welchen Situationen Sie eine andere verwenden würden.
quelle
tuple
Typ haben.iCalendar
und ich wollte Objekte fürBYDAY
undBYSETPOS
. Sie werden in den Kombinationsfeldern angezeigt, aber die tatsächlichen Daten werden in der wiederkehrenden Regelzeichenfolge zusammengefasst, bei der es sich um einekey=value;
Zeichenfolgeart handeltAntworten:
In den meisten Fällen würde ich eher ein Objekt als ein KeyValuePair oder Tuple verwenden. Erstens, wenn Sie 6 Monate später kommen, um Änderungen vorzunehmen, ist es viel einfacher herauszufinden, was Ihre Absicht früher war, als sich zu fragen, was das
Tuple t
ist und warum es diese lustigen Werte hat. Zweitens können Sie, wenn die Dinge wachsen und sich ändern, Ihren einfachen Datenübertragungsobjekten das gewünschte Verhalten geben. Benötigen Sie zwei Namensformate? Einfach, fügen Sie einfach die entsprechenden ToString () -Überladungen hinzu. Benötigen Sie es, um eine Schnittstelle zu implementieren? Kein Problem. Schließlich ist das Erstellen eines einfachen Objekts wirklich mit nahezu null Aufwand verbunden, insbesondere mit automatischen Eigenschaften und Code-Vervollständigung.Bonus Protip: Wenn Sie verhindern möchten, dass diese Objekte Ihren Namespace verschmutzen, ist es eine gute Möglichkeit, private Klassen in Klassen zu integrieren, um Probleme zu vermeiden und ungewöhnliche Abhängigkeiten zu vermeiden.
quelle
Die Regel zum Definieren einer neuen Klasse ist einfach: Sie wird mit "Occam's Razor" zusammengefasst.
http://c2.com/cgi/wiki?OccamsRazor
Stellen Sie keine neuen Klassen ohne guten Grund vor. Oder verwenden Sie so viele vorgefertigte Klassen wie möglich. Oder erfinde so wenig wie möglich. Sie können jedoch problemlos weniger Code schreiben.
Sie können eine vorgefertigte Klasse nicht verwenden, wenn Sie dem Objekt eine eindeutige Verantwortung zuweisen müssen und diese Verantwortung in der vorgefertigten Klasse nicht definiert ist. Oft ist dies eine einzigartige Methode.
Ein
tuple
oderKeyValuePair
ist bevorzugt.Bis um.
Sie benötigen Funktionen, die nicht Teil von A
tuple
oder sindKeyValuePair
. Dann müssen Sie Ihre eigene Klasse definieren.quelle
tuple
oder istKeyValuePair
" betrachten? KeyValuePair hat zumindest eine eingeschränkte Form der Semantik, aber Tupel tun dies selten (möglicherweise in Abhängigkeit vom Kontext) imho. Die Einführung einer neuen Klasse sollte Ihnen selbstverständlich eine klare Semantik geben.Wenn Sie Ihre eigene Klasse schreiben, haben Sie einen klaren Platz, um die Dokumentation über die beiden Werte zu platzieren. Zumal zwei Saiten keine sehr klare Definition sind. Allerdings könnte man sowas schreiben
quelle
MyPair
definiert, was die Tupel-Werte sind und wofür sie verwendet werden.Item1
undItem2
! Ist es nicht genauso einfach, die gesamte Klasse zu definieren?public class SideStrings { public string Left { get; set; } public string Right { get; set; } }
S.Lott schrieb
Lassen Sie mich sagen, warum ich ein ernstes Problem damit habe. Schon seit
scheint in Ordnung zu sein ... ist KeyValue [string, KeyValue [string, KeyValuePair [string, string]]] auch in Ordnung? Ich weiß nicht, was S.Lott dazu sagen wird, aber mein Chef findet es in Ordnung.
Ich traue mich nicht zu widersprechen. Und hier ist der Grund: Es verringert die Lesbarkeit des Codes, der folgen wird. Die Funktion, die eine solche Datenstruktur ausfüllt, ist viel komplexer und fehleranfälliger (err .. exception) (stellen Sie sich zumindest auch eine Geschäftslogik vor). Ich habe nicht zu viel mit meinem Chef gestritten, aber ich sage es hier: Lesbarkeit übertrumpft winzige Platzersparnisse (was sein Argument war). Wäre es nicht ein Klassenobjekt, in dem es einige Felder gibt? aber manche bleiben manchmal leer besser?
PS Ich bin ein Ultra_Noob, also sag mir bitte, wenn ich falsch liege.
quelle
KeyValuePair<string,string>
ist in Ordnung, vorausgesetzt, es handelt sich tatsächlich um Schlüssel und Werte. In diesem Fall ist die Wiederverwendung einer vorhandenen Klasse ein Gewinn, da Sie das Schreiben von Code sparen und die Interoperabilität verbessern. OTOH, etwas so kompliziertes zu verwenden, wieKeyValuePair<string,KeyValuePair<string,string>>
es die meiste Zeit einfach zu kompliziert ist, um praktisch zu sein. Manchmal mag es richtig sein - wenn Sie keine zusätzliche Funktionalität benötigen, wenn die Bedeutung offensichtlich ist und wenn es gut mit anderen Klassen zusammenarbeitet. YMMV, das belastet nur die Vor- und Nachteile.Wenn wir Schlüssel / Wert- Paar sagen , denke ich normalerweise an Hash-Tabellen oder assoziative Arrays oder einfach an ein KeyValuePair- Objekt. Ich benutze sie alle und es gibt keinen Unterschied, wann ich welche benutze.
Ich denke, das Wichtigste an einer Liste von Schlüssel / Wert-Paaren ist, dass Schlüssel eindeutig sein sollten (da es sich immerhin um einen Schlüssel handelt), und alle oben genannten Strukturen bieten mir wirklich diese Funktionalität.
Ansonsten möchte ich nach Tasten suchen oder Aktionen im Array-Stil wie Push und Pop ausführen.
Meine Antwort lautet also NEIN , und ich erstelle keine Objekte explizit für Schlüssel / Wert-Paare, da viele eingebaute Strukturen dies bereits für mich tun.
quelle
Kapitel 6 von Clean Code enthält eine gute Beschreibung, wann eine Datenstruktur im Vergleich zu einer Klasse verwendet werden muss. Kurz gesagt, Sie verwenden eine Datenstruktur, wenn Sie meistens damit rechnen, neue Funktionen hinzuzufügen, um diese Daten zu verarbeiten. Sie verwenden eine Klasse, wenn Sie hauptsächlich damit rechnen, neue Datentypen hinzuzufügen, die von vorhandenen Funktionen verarbeitet werden sollen. Ihre ComboBox ist ein Beispiel für Letzteres. Sie haben eine Reihe von Funktionen (die ComboBox-Implementierung), die mit vielen verschiedenen Datentypen (verschiedenen Datentypen für verschiedene Widgets) arbeiten.
quelle
Ich würde Wilding hier vielleicht zustimmen , aber dann bin ich auch ein bisschen noob in so etwas.
Ich würde vorschlagen, dass die eingebauten Typen häufig Mechanismusobjekte sind. KeyValuePair zum Beispiel ist Teil des Mechanismus eines Wörterbuchs und von Hash-Tabellen, um eindeutige Schlüssel sicherzustellen, und verfügt über Eigenschaften, die im Kontext des Mechanismus selbst aussagekräftige Namen haben.
Auf der anderen Seite bietet die Verwendung von benutzerdefinierten Datenobjekten eine bessere Darstellung Ihrer Daten und viele Vorteile, einschließlich Lesbarkeit und Erweiterbarkeit. Es gibt nichts, was Sie daran hindern könnten, vorhandenen Code in benutzerdefinierten Objekten wie von Sign vorgeschlagen wiederzuverwenden , aber ich würde versuchen, die umgebrochene Klasse auszublenden und Abstraktionslecks zu vermeiden , damit Sie die zugrunde liegende Implementierung zu einem späteren Zeitpunkt ändern können, ohne den Rest Ihres Codes zu beeinträchtigen .
Die eigentliche Frage lautet also : Stellen Sie Daten dar oder verwenden Sie die Daten in einem Mechanismus? (und ich würde nicht raten, diese Konzepte miteinander zu mischen).
Nach meiner Erfahrung gibt es nichts Schlimmeres, als zu sehen, dass ein Tupel [Zeichenfolge, Zeichenfolge] an eine Methode übergeben wird und nicht sofort weiß, was Item1 und Item2 sein sollen. Verwenden Sie Tuples am besten innerhalb von Methoden oder nur als private Mitglieder einer Klasse.
quelle