Hier sind einige Argumente für Eigenschaften und meine Gegenargumente:
Einfacher zu verwenden als Getter- und Setter-Methoden zu schreiben
Getter- und Setter-Methodenpaare sind ein Codegeruch. Wenn Sie es einfacher machen, diese zu schreiben, ist es einfacher, einen Mathe-Test nicht zu bestehen, indem Sie ein Scantron-Formular verwenden und alle Cs ausfüllen. Objekte, die aus Gründen der Persistenz nur den Status enthalten, sollten keine Getter / Setter verwenden und zum Zeitpunkt der Persistenz unveränderliche Objekte erstellen.
Was für einen Verbraucher eines Objekts wichtig ist, ist, was es tut, nicht wie es es tut. Sein Verhalten ist das, was es tut; sein Zustand ist, wie es es tut. Wenn Sie sich um den Zustand eines Objekts kümmern (mit Ausnahme der Persistenz, obwohl dies auch OO bricht), machen Sie einfach kein OOP und verlieren seine Vorteile.
Sie geben den Verbrauchern einen groben Hinweis auf die Leistung
Dies kann sich in Zukunft für jede Immobilie ändern. Angenommen, in Version 1.0 gibt der Zugriff auf PropertyX einfach ein Feld zurück. Wenn das Feld in Version 1.5 null ist, verwendet PropertyX das Nullobjektmuster, um ein neues Nullobjekt zu erstellen. In Release 2.0 wird das Feld durch die Getter-Methode in PropertyX weiter validiert.
Da die Eigenschaft immer komplexer wird, scheint die Leistungsangabe für die Verwendung einer Eigenschaft immer weniger wahr zu sein.
Sie sind besser als öffentliche Felder
Das ist wahr. Aber auch Methoden.
Sie stellen einen grundlegend anderen Aspekt eines Objekts dar als eine Methode, und alle Verbraucher des Objekts sollten sich darum kümmern
Sind Sie sicher, dass beide obigen Aussagen wahr sind?
Sie sind einfacher zu tippen, Mann
Sicher, das Tippen myObject.Length
ist einfacher als das Tippen myObject.Length()
, aber konnte das nicht mit ein wenig syntaktischem Zucker behoben werden?
Warum Methoden anstelle von Eigenschaften verwenden?
Keine Leistungsgarantien. Die API bleibt auch dann wahr, wenn die Methode komplexer wird. Der Verbraucher muss seinen Code profilieren, wenn Leistungsprobleme auftreten, und darf sich nicht auf Word-of-API verlassen.
Weniger für den Verbraucher zu denken. Hat diese Eigenschaft einen Setter? Eine Methode sicher nicht.
Der Verbraucher denkt aus einer richtigen OOP-Denkweise. Als Konsument einer API bin ich daran interessiert, mit dem Verhalten eines Objekts zu interagieren. Wenn ich Eigenschaften in der API sehe, sieht es dem Status sehr ähnlich. Wenn die Eigenschaften zu viel bewirken, sollten sie nicht einmal Eigenschaften sein, also sind Eigenschaften in einem API-ARE-Status so, wie sie den Verbrauchern erscheinen.
Der Programmierer der API wird sich eingehender mit Methoden mit Rückgabewerten befassen und nach Möglichkeit vermeiden, den Status des Objekts in solchen Methoden zu ändern. Die Trennung von Befehlen von Abfragen sollte nach Möglichkeit erzwungen werden.
Ich frage Sie also, warum Sie Eigenschaften anstelle von Methoden verwenden sollten. Die meisten Punkte in MSDN sind Code-Gerüche an und für sich und gehören weder zu Eigenschaften noch zu Methoden.
(Diese Gedanken kamen mir, nachdem ich über CQS nachgedacht hatte.)
type GetFoo() void SetFoo()
zehntausend Mal geschrieben haben. Während meiner gesamten Zeit beim Schreiben von C # -Code war ich noch nie durch eine Eigenschaft verwirrt.Antworten:
Warum ist es "Methoden gegen Eigenschaften"? Eine Methode macht etwas. Eine Eigenschaft ist ein Mitglied eines Objekts. Sie sind völlig verschiedene Dinge, obwohl zwei Arten von Methoden, die üblicherweise geschrieben werden - Getter und Setter - Eigenschaften entsprechen. Da der Vergleich von Eigenschaften mit Methoden im Allgemeinen nicht sinnvoll ist, gehe ich davon aus, dass Sie über Getter / Setter sprechen wollten.
Nicht unbedingt, würde ich argumentieren, aber so oder so geht es nicht um Getter / Setter vs. Eigenschaften, sondern darum, ob beides verwendet werden sollte. Beachten Sie auch, dass Sie z. B. das
setX
Teil weglassen können, genauso wie Sie schreibgeschützte Eigenschaften erstellen können.Eine höchst fragwürdige Einstellung. Wenn die GUI Daten ausgeben möchte, die von a gehalten werden
DataStuffManagerImpl
, muss sie diese Nummer irgendwie abrufen (und nein, es ist keine Option, die Hälfte der Anwendung in die Widget-Klasse zu packen).In fast allen Fällen ist die gesamte Validierungslogik usw. immer noch effektiv O (1) oder auf andere Weise kostengünstig. Wenn nicht, sind Sie vielleicht zu weit gegangen und es ist Zeit für eine Veränderung. Und eine
getX()
Methode wird normalerweise auch als billig behandelt!Eigenschaften sind dieser syntaktische Zucker.
"Gibt es einen Setter für diesen Getter?" Gleicher Unterschied.
Ich bin mir nicht sicher, was Sie uns hier sagen wollen. Für Immobilien gibt es ein noch stärkeres ungeschriebenes Gesetz, um keine Nebenwirkungen zu verursachen.
quelle
obj.x = y
Karten zuobj.setX(y)
undobj.x
Karten zuobj.getX()
. Wie ist das anders?Das ist eine fehlerhafte Annahme und völlig falsch. Get / Set-Methoden sind eine Möglichkeit, ein Datenelement zu kapseln, und stellen in keiner Weise einen "Code-Geruch" dar. Ich hasse es wirklich, wie manche Leute den Begriff "Codegeruch" herumwerfen, aber trotzdem ...
Klingt nach einer schlecht gestalteten API, ich verstehe nicht, wie das an der Eigenschaftssyntax liegt.
Eigenschaften in C # waren einfach syntaktischer Zucker für ein sehr verbreitetes Muster, das unser Leben als Programmierer ein bisschen einfacher machte. Wenn Sie heutzutage jedoch Datenbindungen verwenden möchten, müssen Sie Eigenschaften verwenden, sodass diese jetzt etwas mehr als syntaktischer Zucker sind. Ich glaube, ich stimme wirklich keinem Ihrer Punkte zu und verstehe nicht, warum Sie eine Sprachfunktion nicht mögen, die ein gemeinsames Muster direkt unterstützt.
quelle
Ihre Prämisse ist falsch.
Eigenschaften sind in keiner Weise ein Vertrag zur Leistung oder internen Implementierung oder was auch immer.
Eigenschaften sind spezielle Methodenpaare, die, wenn Sie so wollen, semantisch ein Attribut darstellen. Der einzige Vertrag ist daher, dass sich eine Eigenschaft so verhält, wie Sie es von einem Attribut erwarten würden.
Wenn ich nach der Farbe eines Objekts frage, gehe ich nicht davon aus, ob es durch einen einfachen Feldzugriff erhalten wird oder ob es gerade rechtzeitig berechnet wird.
Der springende Punkt ist, die Möglichkeit zu haben, das Verhalten eines Attributs mithilfe von Methoden verfügbar zu machen, während es für den Benutzer der Schnittstelle transparent ist, unabhängig davon, ob Sie ein Feld oder Accessoren verwenden.
Das Vorhandensein von Attributen (und das tatsächliche Ausblenden ihrer Implementierung, da Eigenschaften im Gegensatz zu Feldern stehen) ist eine leistungsstarke deklarative Funktion, die die Grundlage für visuelle Objektinspektoren und andere automatische Ansichtsgenerierungen, für die Datenbindung und viele andere nützliche Dinge bildet. Und am wichtigsten ist, dass diese Informationen eindeutig auch für Ihre Programmierkollegen übertragen werden.
quelle
Eine Immobilie soll ein Staat sein. Wenn sich der zugrunde liegende Setter- oder Getter-Code ändert, um die zum Festlegen oder Abrufen des Status erforderliche Verarbeitung erheblich zu verbessern, ist dies keine Eigenschaft mehr und Sie sollten ihn durch Methoden ersetzen. Dies liegt bei Ihnen als Entwickler des Codes.
Zu viel Code (wie viel zu viel ist, hängt davon ab) in einen Setter oder Getter einzufügen ist falsch, aber nur weil es möglich ist, ist dies nicht in allen Fällen ein Grund, das Muster wegzuwerfen.
quelle
Eine Sache, die Sie vermissen, und ich weiß nicht, ob dies auf Unwissenheit zurückzuführen ist oder ob Sie dieses Detail absichtlich übersehen, ist, dass Eigenschaften Methoden sind.
Wenn Sie die Eigenschaftssyntax von C # verwenden, erstellt der Compiler leise Getter- und Setter-Methoden mit Metadaten, die Sprachen, die Eigenschaften als erstklassige syntaktische Funktion verstehen, mitteilen, dass sie als solche behandelt werden sollen. Das ist in der Tat der syntaktische Zucker, nach dem Sie fragen. Einige Sprachen, die auf der CLR ausgeführt werden können, verbergen dieses Detail nicht vollständig vor Ihnen (Boo, wenn der Speicher mir dient, und einige Lisp-Implementierungen), und Sie können die Getter und Setter explizit aufrufen.
Eigenschaften haben gelegentlich Nebenwirkungen, wie das Auslösen von Änderungsbenachrichtigungsereignissen (z. B. INotifyPropertyChanged) oder das Markieren einer Instanz einer Klasse als fehlerhaft. Hier haben sie ihren wahren Wert, obwohl das Erstellen etwas mehr Arbeit bedeutet (außer in Boo, das syntaxaffine Makros enthält).
Die umfassendere Frage ist nun, ob Getter- und Setter-Methoden tatsächlich eine gute Sache sind. Es gibt eindeutig Kompromisse; Wenn Sie Mutator-Methoden haben, ist Ihr Code von Natur aus weniger parallelisierbar, da Sie sich jetzt mit Problemen bei der Thread-Synchronisierung befassen müssen. Und es ist durchaus möglich, dass Sie das Risiko eingehen, das Gesetz von Demeter mit Mutator-Methoden zu verletzen (ob Eigenschaften oder Getter / Setter-Methoden; sie sind gleichwertig), weil es so verdammt bequem ist, dies zu tun.
Aber manchmal ist es das Richtige. Manchmal besteht Ihr Problem darin, Daten aus einer Quelle abzurufen, ein wenig zu ändern, die aktualisierten Daten dem Benutzer zu präsentieren und die Änderungen zu speichern. Diese Redewendung wird von Immobilien gut bedient. Wie Allen Holubs Artikel sagt, heißt das nicht, dass Sie sie niemals verwenden sollten, nur weil Getter und Setter Probleme haben. (Papagei abstrakt Guruspeak als schädlich angesehen). Selbst wenn Sie dem Ansatz "Klasse / Verantwortlichkeiten / Mitarbeiter" folgen, werden Sie am Ende entweder Informationen oder Präsentationen von Informationen jemandem zugänglich machen. Es geht darum, die Oberfläche der Verschränkung zu minimieren.
Der Vorteil von Eigenschaften ist, dass es sehr einfach ist, dass ein anderes Objekt sie ausnutzt. Der Nachteil von Eigenschaften ist, dass es sehr einfach ist, dass ein anderes Objekt sie ausnutzt, und das kann man nicht einfach verhindern.
Eine Objektmutation ist auf der Controller-Ebene beispielsweise in einer MVC-Architektur sinnvoll. Das ist dein Mitarbeiter. Ihre Ansicht ist auch ein Kollaborateur, sollte jedoch Ihre Objekte nicht direkt mutieren, da sie unterschiedliche Verantwortlichkeiten hat. Das Einrollen von Präsentationscode in Ihre Geschäftsobjekte ist nicht unbedingt der richtige Weg, um Getter / Setter zu vermeiden.
Die Gleichung ändert sich ein wenig, wenn Sie funktionale Abstraktionen anstelle von reinen OO-Abstraktionen verwenden, was das Erstellen von Kopien eines "Datensatz" -Objekts mit einigen Änderungen im Allgemeinen ziemlich trivial, wenn auch nicht kostenlos macht. Und hey, wenn Sie versuchen, Leistungsgarantien zu erhalten, sind Eigenschaften im Allgemeinen vorhersehbarer als der verzögerte Wiederaufbau einer unveränderlichen Sammlung.
quelle
Ein weiterer wichtiger Grund in meinem Buch für die Verwendung von Eigenschaften ist, dass sie die Lesbarkeit erheblich verbessern können.
ist eindeutig viel weniger lesbar als
quelle
Du hast fast den entgegengesetzten religiösen Standpunkt zu mir :)
Als ich von Delphi nach Java wechselte, war der Mangel an Eigenschaften ein großer Affront gegen mich. Ich war es gewohnt, eine Eigenschaft zu deklarieren und sie entweder direkt auf eine private Variable zu verweisen oder einen (geschützten) Getter & Setter zu schreiben und sie dann auf die Eigenschaft zu "plumbieren". Dies kapselte die Eigenschaft und kontrollierte, wie auf sie eindeutig zugegriffen werden sollte. Sie könnten eine schreibgeschützte Eigenschaft haben, die die Summe beim Zugriff berechnet und sie als "Summe" und nicht als "_getTotal ()" oder ähnliche Ballochs bezeichnet. Dies bedeutete auch, dass Sie den Zugriff auf Eigenschaften einschränken konnten, indem Sie sie in der abstrakten Basisklasse schützen und dann in die Öffentlichkeit verschieben oder in Unterklassen veröffentlichen.
Eigenschaften sind für mich eine natürlichere und ausdrucksstärkere Möglichkeit, den Zustand des Objekts festzulegen und abzurufen. Sich auf nicht erzwungene Codierungskonventionen zu verlassen, ist eher ein "Codegeruch" als alles, wofür Sie Eigenschaften kritisieren. Wie andere bereits gesagt haben, ist es auch eine äußerst schlechte Form, eine schlecht gestaltete Nutzung von Eigenschaften zu finden und ihre Fehler zu nutzen, um das Konzept von Eigenschaften im Allgemeinen zu versuchen und zu verwerfen. Es ist möglich, dass Sie nur eine schlechte Nutzung von Eigenschaften gesehen haben und davon ausgehen, dass dies vermutlich der Fall ist, aber Sie sollten mehr Nachforschungen anstellen, bevor Sie zu dogmatisch werden.
quelle
sorted
Eigenschaft auftrue
. Wenn Sie es also auf einstellen, erhaltenfalse
Sie die ursprüngliche Liste. : D Oder mischt es es zufällig? : D Oder was auch immer, es ist einfach dumm. Außerdem ist es im Vergleich zu einem richtig sortierten Set verdammt langsam. Die Eigenschaften sind nicht schlecht, aber ich habe gelernt, sie sehr sparsam zu verwenden (bis ich mit Getter und Setter ziemlich zufrieden bin; ich verwende hauptsächlich Java).Einer der Gründe, warum Eigenschaften in das Java Beans Framework eingeführt wurden, bestand darin, die Integration in eine IDE zu ermöglichen. Sie können diese Komponenten in die IDE ziehen und die Eigenschaften mithilfe von Eigenschafteneditoren bearbeiten.
(Damals waren sie nur normale Getter und Setter - und wurden nur durch die Namenskonvention definiert - und das roch tatsächlich)
Heutzutage gibt es noch mehr Fälle, in denen auf Eigenschaften zugegriffen und diese nicht über regulären Code geändert werden - beispielsweise beim Debuggen.
quelle
Ein weiterer Aspekt - sie kamen wirklich von VB. Denken Sie daran, dass in den dunklen Tagen des 20. Jahrhunderts, als .NET konzipiert wurde, ein Hauptaugenmerk darauf lag, dass es ein einfacher Ersatz für VB war, sodass Ihre VB-Programmierer Dinge einfach per Drag & Drop auf Webformulare ziehen konnten. VB hatte Eigenschaften, daher mussten Sie diese Funktion beibehalten, damit die Dinge richtig übersetzt werden konnten.
quelle
Es gibt mindestens zwei Zwecke für Eigenschaften:
Sie sind konzeptionell identisch mit Feldern, auch wenn sie unterschiedlich implementiert sind . Ein Getter sollte den Zustand des Objekts nicht ändern und keine Nebenwirkungen haben. Ein Setter sollte den Status nur auf eine Weise ändern, die konzeptionell der Änderung eines Feldes ähnelt, und keine anderen Nebenwirkungen haben.
Sie sind syntaktisch identisch mit öffentlichen (möglicherweise schreibgeschützten) Feldern. Dies bedeutet, dass ein öffentliches Feld in eine Eigenschaft geändert werden kann, ohne dass Anrufer auf Quellenebene unterbrochen werden.
quelle