wann ein Parameter übergeben werden soll und wann eine Instanzvariable verwendet werden soll


92

Wie entscheidet ihr euch, etwas lokal zu verfolgen und es dann einfach an jede Methode zu übergeben, die ihr aufruft, oder eine Instanzvariable zu deklarieren und in den Methoden zu verwenden?

Ich bevorzuge Instanzvariablen, die in einer Liste am Ende der Klasse gespeichert sind. Aber wenn meine Programme immer komplizierter werden, wird diese Liste immer länger ... Ich denke, wenn etwas oft genug passiert wird, sollte es nur für alle Jungen und Mädchen sichtbar sein, die es brauchen, aber dann frage ich mich: "Warum nicht einfach alles öffentlich machen? Dann müssen Sie überhaupt nichts mehr weitergeben!"


1
Wenn Sie ein bestimmtes Beispiel haben, erhalten Sie möglicherweise direktere nützliche Antworten
Brabster

Antworten:


54

Da Sie sich auf Instanzvariablen beziehen, gehe ich davon aus, dass Sie in einer objektorientierten Sprache arbeiten. Bis zu einem gewissen Grad ist es subjektiv, wann Instanzvariablen verwendet werden, wie ihr Umfang definiert wird und wann lokale Variablen verwendet werden. Es gibt jedoch einige Faustregeln, die Sie beim Erstellen Ihrer Klassen befolgen können.

  • Instanzvariablen werden normalerweise als Attribute einer Klasse betrachtet. Stellen Sie sich diese als Adjektive des Objekts vor, das aus Ihrer Klasse erstellt wird. Wenn Ihre Instanzdaten zur Beschreibung des Objekts verwendet werden können, ist es wahrscheinlich sicher, dass es eine gute Wahl für Instanzdaten ist.

  • Lokale Variablen werden im Rahmen von Methoden verwendet, um ihre Arbeit abzuschließen. Normalerweise sollte eine Methode den Zweck haben, einige Daten abzurufen, einige Daten zurückzugeben und / oder einen Algorithmus für einige Daten zu verarbeiten / auszuführen. Manchmal ist es hilfreich, sich lokale Variablen als Mittel vorzustellen, um eine Methode von Anfang bis Ende zu unterstützen.

  • Der Bereich der Instanzvariablen dient nicht nur der Sicherheit, sondern auch der Kapselung. Gehen Sie nicht davon aus, dass "das Ziel darin bestehen sollte, alle Variablen privat zu halten". In Fällen der Vererbung ist es normalerweise eine gute Alternative, Variablen als geschützt festzulegen. Anstatt alle Instanzdaten als öffentlich zu markieren, erstellen Sie Getter / Setter für diejenigen, auf die nach außen zugegriffen werden muss. Stellen Sie nicht alle zur Verfügung - nur die, die Sie benötigen. Dies wird während des gesamten Entwicklungslebenszyklus geschehen - es ist von Anfang an schwer zu erraten.

Wenn es darum geht, Daten in einer Klasse weiterzugeben, ist es schwierig zu sagen, was Sie tun, ist eine gute Praxis, ohne Code zu sehen. Manchmal ist es in Ordnung, direkt mit den Instanzdaten zu arbeiten. andere Male ist es nicht. Meiner Meinung nach ist dies etwas, das mit Erfahrung einhergeht - Sie werden eine gewisse Intuition entwickeln, wenn sich Ihre objektorientierten Denkfähigkeiten verbessern.


Meine Antwort wäre, diese Antwort zur H-Man2-Antwort (Lebensdauer) hinzuzufügen. Es sollte genau dann ein Mitgliedsattribut sein, wenn es sich um einen dauerhaften Status des Objekts handelt. Das heißt, der Wert ist für sich genommen außerhalb des Bereichs des aktuellen Methodenstapels sinnvoll.
David Rodríguez - Dribeas

Meine Bauchreaktion ist, David und H-MAn2 zuzustimmen. Ich lese jedoch "sauberen Code" von Robert c Martin und in Kapitel 3 überarbeitet er den Code, um etwas von einem Methodenparameter in eine Mitgliedsvariable zu verschieben, da es schlecht ist, viele Parameter zu haben. Alles in allem denke ich, wenn Ihre Klasse nur eine einzige Verantwortung hat, ist die Lebensdauer des Objekts dieselbe wie die Lebensdauer dieser Berechnung. Vielleicht lautet die eigentliche Antwort: Wenn Sie diese Frage stellen müssen, ist Ihre Klasse zu groß?
Andy

@ DavidRodríguez-dribeas was meinst du mit method stack?
committedandroider

@committedandroider: Wenn der Wert den aktuellen Funktionsaufruf überlebt
David Rodríguez - Dribeas

45

Dies hängt hauptsächlich von der Lebensdauer der Daten ab, die Sie in der Variablen speichern. Wenn die Daten nur während einer Berechnung verwendet werden, übergeben Sie sie als Parameter. Wenn die Daten an die Lebensdauer des Objekts gebunden sind, verwenden Sie eine Instanzvariable.

Wenn Ihre Liste von Variablen zu lang wird, ist es vielleicht ein guter Punkt, darüber nachzudenken, einige Teile der Klasse in eine neue Klasse umzuwandeln.


21

Meiner Meinung nach sind Instanzvariablen nur erforderlich, wenn die Daten über Aufrufe hinweg verwendet werden.

Hier ist ein Beispiel:

myCircle = myDrawing.drawCircle(center, radius);

Mit der Abbildung der myDrawing-Klasse werden nun 15 Hilfsfunktionen zum Erstellen des myCircle-Objekts verwendet. Jede dieser Funktionen benötigt den Mittelpunkt und den Radius. Sie sollten immer noch nicht als Instanzvariablen der myDrawing-Klasse festgelegt werden. Weil sie nie wieder gebraucht werden.

Andererseits muss die myCircle-Klasse sowohl den Mittelpunkt als auch den Radius als Instanzvariablen speichern.

myCircle.move(newCenter);
myCircle.resize(newRadius);

Damit das myCircle-Objekt bei diesen neuen Aufrufen den Radius und die Mitte erkennt, müssen diese als Instanzvariablen gespeichert und nicht nur an die Funktionen übergeben werden, die sie benötigen.

Instanzvariablen sind also im Grunde eine Möglichkeit, den "Status" eines Objekts zu speichern. Wenn eine Variable nicht erforderlich ist, um den Status eines Objekts zu kennen, sollte sie keine Instanzvariable sein.

Und um alles öffentlich zu machen. Es könnte Ihr Leben im Moment einfacher machen. Aber es wird zurückkommen, um dich zu verfolgen. Bitte nicht.


Sie können jedoch auch move definieren, um die Parameter (oldCenter, newCenter) zu verwenden.
obesechicken13

4

MEINER BESCHEIDENEN MEINUNG NACH:

Wenn die Variable Teil des Status der Instanz ist, sollte es sich um eine Instanzvariable handeln - Klasseninstanz HAS-A-Instanzvariable.

Wenn ich wiederholt etwas an die Methoden einer Instanz übergeben würde oder eine große Anzahl von Instanzvariablen hätte, würde ich wahrscheinlich versuchen, mein Design zu überprüfen, falls ich etwas verpasst oder irgendwo eine schlechte Abstraktion vorgenommen hätte.

Ich hoffe es hilft


3

Natürlich ist es einfach, eine große Liste öffentlicher Variablen in der Klasse zu führen. Aber auch intuitiv kann man erkennen, dass dies nicht der richtige Weg ist.

Definieren Sie jede Variable kurz bevor Sie sie verwenden. Wenn eine Variable die Funktion einer bestimmten Methode unterstützt, verwenden Sie sie nur im Bereich der Methode.

Denken Sie auch an die Sicherheit. Eine Variable der öffentlichen Klasse ist anfällig für unerwünschte Änderungen durch "externen" Code. Ihr Hauptziel sollte es sein, alle Variablen privat zu halten, und jede Variable, die dies nicht ist, sollte einen sehr guten Grund dafür haben.

Wenn Parameter auf dem gesamten Stapel übergeben werden, kann dies sehr schnell hässlich werden. Als Faustregel gilt, dass Ihre Methodensignaturen sauber und elegant bleiben. Wenn Sie viele Methoden sehen, die dieselben Daten verwenden, entscheiden Sie entweder, ob es wichtig genug ist, ein Klassenmitglied zu sein, und wenn dies nicht der Fall ist, überarbeiten Sie Ihren Code, damit er sinnvoller wird.

Es läuft auf gesunden Menschenverstand hinaus. Überlegen Sie genau, wo und warum Sie jede neue Variable deklarieren, welche Funktion sie haben soll, und treffen Sie von dort aus eine Entscheidung darüber, in welchem ​​Bereich sie leben soll.


Sie möchten häufig, dass Methoden öffentlich sind, damit Sie sie in einem Unit-Test testen können.
obesechicken13
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.