2010-08-01 7 views
6

Einer der Ratschläge von Joshua Bloch ist, dass Klasse sollte als unveränderlich gestaltet werden.Unveränderbare Klasse Design

ich die folgende Klasse haben

public class Dividend { 
    public Dividend setDate(SimpleDate date) { 
     Dividend dividend = new Dividend(this.getStock(), this.getAmount(), date); 
     return dividend; 
    } 
.....// More to go. 

Für setDate Methode dieses Objekt wird nicht verändert werden.

Stattdessen wird eine Kopie des dieses mit seinem Datumsfeld, das geändert wird, zurückgegeben.

Allerdings, durch die Beurteilung von der Methode Name, wie wird der Benutzer wissen dieses Objekt wird immer noch unveränderlich bleiben?

Gibt es eine bessere Namenskonvention neben setDate?

+2

Hat die Klasse 'Divident' eine Methode' setComment', die das Objekt modifiziert? Dann ist es nicht unveränderlich. – Jesper

+0

Wenn Ihre setComment-Methode privat ist, ist nur diese Klasse unveränderlich. – Gopi

+5

Anstelle von 'setDate' können Sie Dinge wie' onDate'/'withDate' /' forDate' usw. ausprobieren. – polygenelubricants

Antwort

10

Wenn Sie Setter haben, wird Ihre Klasse veränderlich aussehen, und Benutzer werden es wahrscheinlich falsch verwenden. Sie werden wahrscheinlich es so nennen:

dividend.setDate(myDate); 

Und dann wundern, warum die dividend ‚s Datum nicht ändern. Sie sollten es so verwendet haben:

newDividend = dividend.setDate(myDate); 

Um die API intuitiver zu gestalten, wäre es besser, die setDate Methode, um so etwas wie copyWith zu umbenennen:

newDividend = dividend.copyWith(myDate); 

Oder, wenn Sie viele Felder haben und das Überladen wäre verwirrend, man könnte sie copyWithDate und copyWithComment nennen.

Andere Namen sind auch möglich, wie in den anderen Antworten angegeben: derive (und deriveWithDate) oder einfach withDate.

1

Sie sollten Ihre Klasse genau wie eine String-Klasse implementieren, die keine Setter enthält. Es versteht sich, dass es unveränderlich ist, wenn niemand etwas darauf setzen kann. (Vielleicht möchten Sie vielleicht die Setter privat machen oder Sie können nur die Variablen direkt aus Ihrem Dividend Klasse einstellen möchten)

3

Font zum Beispiel hat (a) derive Methode (n), die neue Schriftart-Instanzen erstellen abgeleitet von der aktuellen.

+0

stimme zu - Ich finde die Namensgebung der Ableitung ziemlich intuitiv. – mikera

-1

Diese Funktion ist nur ein Wrapper für den Konstruktor. Überladen Sie den Konstruktor, um ein vollständiges zu kopierendes Dividendenobjekt zu akzeptieren. Andernfalls könnten Sie diese Funktion getDividend umbenennen (es ist definitiv kein Setter).

2

Viele Java-Bibliotheken, die ich gesehen habe, beginnen, with als Präfix für 'eine Kopie dieses Objekts, mit die folgenden Änderungen' zu verwenden.

Zum Beispiel:

public Dividend withDate() { 
    .... 

die sich

Dividend newDividend = oldDividend.withDate(...).withAmount(...).withComment(...); 

JSR-310, beispielsweise

verleiht, folgt diesem Muster (sowie unter Verwendung von plusXxx() und minusXxx() für 'Teller' Objekte, die eine Delta nehmen eher als ein absoluter Wert, zum Beispiel).

-1

Da eine Dividend zurückgegeben wird, werden Benutzer wahrscheinlich wissen, dass es eine neue Dividend Instanz ist. Selbst dann könnten Sie den Namen noch einmal überdenken.

+0

Ich würde annehmen, dass es eine fließende Schnittstelle war und "dieses" zurückgab, wenn ich nicht wusste, dass es unveränderlich war. – ILMTitan

Verwandte Themen