2010-05-27 14 views
22

wir verwenden ASP.NET mit C# und basierend auf Open-Source-Projekte/Artikel, die ich durchgereicht habe, fand ich viele Eigenschaften einschließlich einer Logik aber wenn ich so tat die Team- Leiter sagte mir, es ist überhaupt nicht gut, Logik in Eigenschaften zu platzieren, sondern die Logik durch Methoden aufrufen ...Ist es eine gute Praxis, Logik in Eigenschaften zu implementieren

ist das wirklich schlimm? und warum nicht Logik in den Eigenschaften verwenden?

Dank,

+0

eigentlich redete der Team-Leader darüber, Logik nicht in den Getter-Teil zu bringen! Also refaktoriere ich meine Eigenschaft "Methode extrahieren" während der Aufgabenüberprüfung. –

Antwort

32

Der Zugriff auf die Eigenschaften wird sofort erwartet (keine langen Wartezeiten), konsistent (keine Änderung der Werte) und sicher (keine Ausnahmen). Wenn Sie diese Garantien geben können, denke ich, Logik in Eigenschaften zu setzen ist in Ordnung.

+1

Mit konsistent meinen Sie [idempotent?] (Http://en.wikipedia.org/wiki/Idempotenz) –

+11

Ausnahmen sind in Ordnung auf Setter, wenn jemand versucht, einen illegalen Wert zu setzen. – Thorarin

+0

Idempotent würde gelten denke ich. Ich würde den Ausnahmen bei den Settors zustimmen, aber ich denke, Sie sollten definitiv keine Ausnahme auf einen Getter werfen. –

28

Es ist in Ordnung einige Logik in Eigenschaften haben. Zum Beispiel sind die Validierung von Argumenten in Setter und die Lazy-Berechnung in Gettern ziemlich üblich.

Es ist in der Regel eine schlechte Idee für eine Eigenschaft Zugriff auf etwas teures wie eine Datenbank-Aufruf jedoch zu tun. Entwickler neigen dazu, anzunehmen, dass Immobilien relativ günstig bewertet werden können.

Es ist ein Urteilsspruch am Ende - aber ich lehne sicher den Vorschlag ab, dass Eigenschaften immer nur trivial sein sollten, soweit sie mit automatischen Eigenschaften implementiert werden könnten.

+0

Ich stimme der Antwort zu, aber was ist mit datengetriebenen Situationen, in denen ein "Produkt" einen "Lieferanten" und einen "Lieferanten" eine Sammlung von "Produkten" hat? Sollten Sie diese verwandten Entitäten während der Objektkonstruktion laden? Erster Eigentumszugang? Oder sollten sie aufgrund der Fallstricke, die beide Optionen bieten, nicht über Immobilien abgerufen werden? –

+0

@Anthony - Ich glaube nicht, das Laden der Eigenschaften auf dem Objekt liegt in der Verantwortung des Objekts selbst, sondern die Verantwortung Ihrer Datenzugriffsebene oder ORM. – tvanfosson

+0

@Anthony: Deshalb setze ich "normalerweise" :) Dinge wie Linq zu Sql können tatsächlich so etwas tun - aber ich würde erwarten, dass Entwickler wissen, dass sie mit ORM-gebundenen Objekten zu tun haben. Es ist nicht die Art von Sache, die ich überall sehen möchte. –

9

. Sie sind nur Abkürzungen für Getter/Setter. Jede Logik, die in einem Getter/Setter gültig wäre, ist vernünftig, um eine Eigenschaft einzufügen. Jede Logik, die Sie normalerweise nicht in einen Getter/Setter einfügen würden, wäre unangemessen, um eine Eigenschaft einzufügen. Wenn Sie (als Konsument der Klasse) nicht wirklich erwarten können, dass ein Eigenschaftswert festgelegt wird, oder noch schlimmer, wenn ein Eigenschaftswert dazu führt, dass ein Verhalten stattfindet, dann gehört diese Logik wahrscheinlich woanders hin. Mit anderen Worten, die Logik sollte verwandt und konsistent sein mit dem Abrufen oder Festlegen der Eigenschaft.

aus dem verlinkten Artikel Zitiert oben:

Eigenschaften Mitglieder sind, die einen flexiblen Mechanismus zum Lesen zur Verfügung stellen, schreiben oder die Werte der privaten Felder berechnen. Eigenschaften können verwendet werden, als ob sie öffentliche Datenelemente sind, aber sie sind tatsächlich spezielle Methoden namens Accessoren. Dies ermöglicht den einfachen Zugriff auf die Daten und bietet gleichzeitig die Sicherheit und Flexibilität der Methoden .

+0

Welche Art von Logik ist in einem Getter/Setter gültig? –

+1

@Robert - es ist schwer, eine umfassende Definition zu geben, aber es sollte den Geruchstest bestehen. Zum Beispiel ist es vernünftig zu erwarten, dass eine Änderung des Preises oder der Menge einer Bestellung die Kosten ändern würde. Sie würden nicht erwarten, dass es den Lieferanten ändert, von dem es geliefert wird. – tvanfosson

+0

Stimmen Sie prinzipiell zu, obwohl ich Klassen geschrieben habe, die aus Textdateien lesen, wo beim Festlegen einer bestimmten Eigenschaft die Datei an den Anfang zurückgespult wird (weil das Festlegen dieser bestimmten Eigenschaft den Dateileser andernfalls in einen ungültigen Zustand versetzt). –

4

Eine allgemeine Antwort gilt hier: Es hängt davon ab.

Im Allgemeinen ist es keine gute Idee, Geschäft Logik in Getter und Setter zu implementieren. Wenn Ihr Objekt ein einfaches DTO (Datenübertragungsobjekt) ist, würde dies die Einzelverantwortlichkeit verletzen.

Allerdings finden sich in den Eigenschaften oft Status-Tracking-Logik und andere Haushaltsfunktionen. Entity Framework 4 Self-Tracking-Entitäten verfügen z. B. in jedem primitiven Property-Setter über eine Statusverwaltungslogik, um die Verfolgung zu ermöglichen.

Eine Alternative zur Logik in Eigenschaften ist die aspektorientierte Programmierung (AOP). Mit AOP können Sie Logik zwischen Objekten und dem Hosting-Prozess "injizieren".Der Zugriff auf Objekte kann "abgefangen" werden und bedingt gehandhabt werden.

+0

Einverstanden, Sie fassten zusammen, was ich dachte. :) In einem kleinen Tierprojekt, das ich habe, habe ich etwas Logik in eine "Player" -Klassen-Eigenschaft aufgenommen, um das Team eines Spielers im Spiel zu setzen. Es prüft zunächst, ob das aktuelle Team des Spielers und der Wert des neuen Teams nicht identisch sind und sendet dann einen Konsolenbefehl, um das Team des Spielers auf den Wert zu ändern. – Zack

0

Normalerweise betrifft eine Eigenschaft nur 1 Variable, da sie hauptsächlich für diesen Zweck erstellt wurde. Aber irgendwann wollen Sie eine höhere Eigenschaft, die nicht nur eine 1-zu-1-Variable ist. In diesem Fall ist es normal, dass es Code enthält. Aber Sie müssen bedenken, dass eine Eigenschaft nicht als eine Funktion verwendet werden soll. Wenn Sie eine Funktion aufrufen, wissen Sie, dass sie etwas verarbeitet. Wenn Sie eine Eigenschaft aufrufen, erwarten Sie, dass sie schnell ist.

Aber schließlich ist es eine Frage der Vorlieben, und wie Kodierung Standard, nach dem, was Ihr Vorgesetzter Ihnen sagt, ist in Ihrem Ermessen. Es ist also nicht schlecht und hängt von deinem Urteil ab.

0

Meiner Meinung nach ist Geschäftslogik in Setter/Getter nur in bestimmten Situationen erlaubt. Zum Beispiel: Es ist erlaubt, eine Logik zu setzen, die für die Validierung der Eingabe verantwortlich ist, da Setter für den Erhalt des Objektstatus verantwortlich sind, so dass der Status nicht verletzt werden sollte. Daher sollten Sie diese Geschäftslogik auf den kleinsten Teil des Codes reduzieren, der nur für ein Thema verantwortlich ist.

Die andere Sache ist, dass Ihre Klasse (in der besten Situation) POCO sein sollte. Warum? Weil es wiederverwendbar sein sollte und wenn die Klasse Logik in Eigenschaften enthält, kann die Wiederverwendbarkeit einfach blockiert werden. Denken Sie, dass Sie SqlServerPerson mit einigen SQLServer-Validierung in Eigenschaften haben, dann kann es schwierig sein, es durch zum Beispiel NHibernatePerson zu ersetzen, wenn Sie den ORM/DB-Zugriff ändern.

1

Das Platzieren von Geschäftslogik in einem Setter kann Probleme verursachen, wenn Sie Objekte mit JSon, XML oder einem ORM serialisieren/deserialisieren müssen. Ein Beispiel hierfür ist die Verwendung eines NoSql-Datenspeichers wie einer Dokumentendatenbank oder eines ORM. Einige von diesen (z. B. NHibernate) können so konfiguriert werden, dass sie auf Unterstützungsfelder anstelle des Setter zugreifen.

Ich finde, dass die Verwendung eines öffentlichen Getter und Private Setter zusammen mit einer Methode, um den Wert mit zusätzlicher Logik als erforderlich festzulegen ist ein guter Ansatz. Die meisten Serializer können auf den privaten Setter zugreifen, sodass Sie eine genaue Darstellung des persistenten Objekts erhalten, ohne versehentlich eine Logik auszulösen, die bei der Deserialisierung möglicherweise Werte falsch ändert.

Wenn Sie jedoch nicht glauben, dass jemals eine Serialisierung/Deserialisierung erforderlich sein wird, sollte dies kein Problem sein.

1

Meiner Meinung nach ist das absolut in Ordnung. So wie ich das sehe, ist die einzige Rechtfertigung dafür, dass Eigenschaften in erster Linie ein Sprachfeature sind, darin zu suchen, dass sie Logik in sich tragen können. Andernfalls können Sie auch direkten Zugriff auf die zugrunde liegenden Datenelemente zulassen.

+1

Ein bisschen dachte immer das Gleiche: Access-Modifikatoren ist ein weiterer Grund, und explizite Deklaration, um Logik in sie einzubetten ... Obviously den Kontext der Klasse im Hinterkopf behalten ... –

Verwandte Themen