tags:

views:

182

answers:

7

One of the advice given by Joshua Bloch is that, class should be designed as immutable.

I have the following class

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

For setDate method, this object will not be modified.

Instead, a clone copy of this with its date field being modified will be returned.

However, by judging from the method name, how does the user will know this object will still remain immutable?

Is there a better naming convention besides setDate?

+8  A: 

If you have setters, your class will look mutable, and users will probably use it the wrong way. They'll probably call it like this:

dividend.setDate(myDate);

And then be surprised why the dividend's date didn't change. They should have used it like this:

newDividend = dividend.setDate(myDate);

To make the API more intuitive, it would be better to rename the setDate method to something like copyWith:

newDividend = dividend.copyWith(myDate);

Or, if you have many fields and overloading would be confusing, you could call them copyWithDate and copyWithComment.

Other names are possible too, as stated in the other answers: derive (and deriveWithDate), or simply withDate.

jqno
+1  A: 

You should implement your class just like a String class, which has no setters on it. It will be understood that it is immutable if nobody can set anything on it. (maybe you might want to make the setters private or you might just want to set the variables directly from inside your Dividend class)

Romain Hippeau
+3  A: 

Font, for example, has (a) derive method(s) which create new font instances derived from the current one.

mklhmnn
agree - I find the derive naming quite intuitive.
mikera
A: 

This function is just a wrapper for the constructor. Overload the constructor to accept a full dividend object to copy. Otherwise, you could rename this function getDividend (it definitely isn't a setter).

Anthony DiSanti
A: 

Is the immutability suggestion the only reason you want to enforce immutability? Maybe in your particular case a mutable class makes more sense and will make api more clear.

I would not recomment false setter as the one you proposed anyway, it is confusing. I would rather go with jqno's approach or a separate factory to construct new Dividend instances, possibly including a prototype parameter to copy data from. They could have create/construct/make prefix in their name.

mrembisz
+1  A: 

Many Java libraries I've seen are starting to use with as the prefix for 'a copy of this object, with the following changes'.

For example:

public Dividend withDate() {
   ....

which lends itself to

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

JSR-310, for example, follows this pattern (as well as using plusXxx() and minusXxx() for 'adjuster' objects which take a delta rather than an absolute value, for example).

Cowan
A: 

Since a Dividend is being returned, users will probably know it is a new Dividend instance. Even then, you might reconsider the name.

fastcodejava
I would assume it was being a fluent interface and returning `this` if I was unaware it was immutable.
ILMTitan