2009-02-25 13 views
3

Es gibt viele reden über Getters und Setter sein "böse" und was nicht.Ist dieser Setter 'böse'

Meine Frage ist: ist der folgende Setter böse? (Rest der Klasse wird der Kürze halber weggelassen)

int balance 

public void deposit(int amount) 
{ 
    this.balance += amount; 
} 

Diese Klasse emuliert einen Geldautomaten. Im Vereinigten Königreich gibt es ein paar Geldautomaten, mit denen Sie sowohl einzahlen als auch abheben können, daher benötigt dieses Objekt eine Möglichkeit, seinen Zustand (die Balance) zu ändern. Ist dieser Setter 'böse'?

+1

setBalance/doDeposit – vladr

+8

Dies ist nicht ein Setter. –

Antwort

8

Abgesehen von der Tatsache, dass es keine Behandlung außergewöhnlicher Bedingungen gibt, sieht es wie eine vollkommen gute OO-Methode aus - es heißt, was es tut, und es tut, was man erwartet.

3

Für eine Klasse gibt es nichts Böses daran, einen Wert über einen Setter zu setzen, aber das ist mehr eine Funktion als ein direkter Setter. Ja, es legt den Wert einer Eigenschaft fest, aber es tut dies durch Addition, anstatt den vorherigen Wert zu ersetzen, und die Namen werden nicht aneinandergereiht.

Ein echter ‚Setter‘ würde aussehen wie folgt aus:

int balance 

private void setBalance(int amount) 
{ 
    this.balance = amount; 
} 

public void deposit(int amount) 
{ 
    setBalance(this.balance + amount); 
} 

Für Ihre spezifischen ATM Problem, aber ich bezweifle sehr, dass ein ATM eine Einzahlung auf Ihr Konto fügt sofort. Es muss wahrscheinlich gesammelt und über einen separaten Mechanismus gebucht werden.

+0

Jetzt sieht das wie Setter böse aus. Ein Hauptvorteil der Verwendung eines Setter besteht darin, ihn zur Benutzer-API zum Festlegen eines Werts zu machen. Die zugrunde liegende Logik kann sich ändern und der Benutzercode ist nicht betroffen. In diesem Beispiel ist es privat und gewinnt nichts an Design. – spoulson

+0

Diese Implementierung bringt nichts - aber wenn sie anfangen müssen, auch jeden Balance-Wechsel zu protokollieren, ist es schön, bereits alle diese Änderungen an einem Ort durchzusetzen. –

+0

Ich stimme zu. Dieses Design hat jedoch keine Auswirkungen auf den Benutzer. Das Ändern des Codes von einem privaten Feld in einen privaten Setter würde die Benutzer-API nicht ändern, so dass es nur eine unbenutzte Abstraktionsebene wird, bis Sie den Protokollierungscode dort eingegeben haben. – spoulson

1

Nun, Sie würden auf negative Beträge, eine Nullmenge, etc überprüfen ... aber geben Sie die Anforderung, es ist in Ordnung.

Folgen Sie dieser Faustregel: Jede Variable, die Sie erstellen, sollte endgültig sein, es sei denn, sie muss geändert werden und setzt keine Methoden für Instanzvariablen, außer Sie möchten sie wirklich außerhalb der Klasse ändern.

0

Nicht unbedingt; Sie erwähnen, dass Sie das Verhalten eines Geldautomaten (Geldautomaten) emulieren wollen. Und Sie befürchten, dass Sie mit Geldautomaten sowohl einzahlen als auch abheben können. Aber diese Operationen, die Ein- und Auszahlung, müssten serialisiert werden. Du brauchst alle deine Aktionen atomar, also ist diese Art von Methode besser als eine, bei der du versuchst, mehr Dinge zu tun.

8

Ich glaube nicht, dass das gemeint ist, wenn Leute über Getter und Setter sprechen, weil dies nicht einfach einen Member auf den gegebenen Wert setzt.

Ich kümmere mich nicht um Setter und Getter, sondern vor allem, weil ich an meine "Objekte" als übergeordnete Entitäten in der Codebasis denke. Z.B. (IMO) wäre es „mehr falsch“ sein, den Betrieb außerhalb der Klasse zu tun:

account.SetBalance(account.GetBalance() + depositAmount) 

Stattdessen haben Sie implementiert geordnete Funktionalität in Ihrem Objekt; Sie machen eine Einzahlung und lassen das Objekt den richtigen Umgang damit herausfinden. Dies erlaubt eine viel zentralere Handhabung von außergewöhnlichen Bedingungen als das obige Getter/Setter-Beispiel.

+1

+1 Gutes Beispiel dafür, was Getter und Setter "böse" macht. – Chuck

0

Ein Problem, das ich sehe, ist, dass Sie einen integralen Typ verwenden, wenn Sie mit Geld umgehen. Kein Problem, wenn es sich um eine Festkomma-Nummer handelt, aber es gibt keinen Hinweis darauf, dass dies der Fall ist.

2

Persönlich würde ich das eine Methode nennen, kein Setter. Die stereotypisch Setter würde

public void deposit(int new_balance) 
{ 
    this.balance = new_balance; 
} 

Alles sei es tut, ist Ihnen direkten Zugang zu den Interna der Klasse geben, also einen Wert von ihnen Einkapseln gewonnen zu besiegen und die Beschränkung des Zugangs.Deshalb mögen die Leute sie nicht.

+0

Also, eine Mutator-Methode unterscheidet sich von einer Setter? –

0

IMO, der ATM sollte nicht "Balance" als Feld haben.

(zusätzlich, Ihre ‚Einzahlung‘ Methode ist kein Setter)

Sie wahrscheinlich Konto-Objekt mit einer ‚Balance‘ Feld und möglicherweise eine bequeme Methode ‚modifyBalance‘ drauf haben sollten, die einen positiven Wert annimmt, um Inkrementieren oder einen negativen Wert, um die Balance zu verringern.

Dann würden Ihre ATM-Methoden 'modifyBalance' für das Account-Objekt aufrufen, wenn diese Art von Transaktionen ausgeführt wird.

0

Sie können nicht feststellen, ob eine einzelne Methode böse ist oder nicht, sie hängt vom Kontext ab und davon, wer Zugriff auf das Objekt hat.

Wenn Sie Getter und Setter für alle Felder haben und jeder und sein Hund Zugriff auf das Objekt haben, dann ist das sehr schlecht, da es im Wesentlichen keine Einkapselung der Daten gibt.

Wenn Sie andererseits nur für die Felder, die es benötigen, Setter haben und das Objekt nur einigen wenigen anderen Objekten bekannt ist, die mit ihm kommunizieren müssen, dann wäre das ganz in Ordnung.

4

Ist das eine Trickfrage? Ich frage, weil die zur Verfügung gestellte Methode nicht einmal eine "Setter" -Methode ist. Es ist eine Operation, keine Eigenschaft. Setter und Getter sind in der Regel Accessormethoden für private Variablen (Eigenschaften). Also ich denke, die Antwort auf Ihre Frage lautet:

Das ist kein Setter, aber als eine allgemeine Methode, die eine Operation an einem Objekt durchführt, ist es überhaupt nicht böse.

0

Das ist kein Setter. Das ist eine normale Methode (oder Member-Funktion oder was auch immer).

Ein Setter ist eine Funktion, die eine gegebene Variable auf einen bestimmten Wert setzt und normalerweise eine schlechte Idee ist. Eine Methode ist eine Funktion, die eine bestimmte Klassenoperation ausführt. Es ist in Bezug auf die Klasse sinnvoll.

Wenn Sie eine seltsame Datenstruktur haben, haben Sie möglicherweise keine "Balance" Variable. Unabhängig von Ihrer Datenstruktur müssen Sie eine "Einzahlungs" -Funktion haben. Es gibt einen Teil des Unterschieds.

0

das kein Setter ist, es ist ein normales Verfahren

auch wenn es ein Setter war, ist es nicht böse

das ist ein böser Setter

int _balance = 0; 
public int Balance() 
{ 
    get { return _balance; } 
    set { } //now that's evil! 
}