How to write a class for immutable object?

H

hiwa

How to declare, define and implement a class that represents an
immutable object?

In other words, for what traces in their source codes and APIs
could we discern Java API String, Long et al are classes for
immutables?

JLS tells nothing, no mutable/immutable words in its index. The
archive of cljp seems to have nothing relevant too.
 
A

Andrew McDonagh

hiwa said:
How to declare, define and implement a class that represents an
immutable object?

In other words, for what traces in their source codes and APIs
could we discern Java API String, Long et al are classes for
immutables?

JLS tells nothing, no mutable/immutable words in its index. The
archive of cljp seems to have nothing relevant too.

immutability is a concept rather than any keyword within the JLS.

Basically any class is immutable , so long as there is no way of
modifying its contents after creation.

e.g immutable class .

class A {
public A(int valueToUse) {
value = valueToUse;
}


public int getValue() {
return value;
}

private int value;
}


A's int value can only be set at construction, not after.


However, if we added the following method to A:

public void setValue(int valueToUseNow) {
value = valutToUseNow;
}

Then we could change 'value' after construction and this class is deemed
to be mutable.

HTH

Andrew
 
A

Andrew McDonagh

Daniel said:
Additionally the class should be declared final. Although a sub-class
cannot access the value member directly, it can over-ride getValue() to
return something different.

Dan.

true, though in practise, i rarely do this with classes that are not
reused by other systems. I usually name the class Immutable... which
reminds us all that its supposed to be immutable.
 
T

Tony Morris

Andrew McDonagh said:
true, though in practise, i rarely do this with classes that are not
reused by other systems. I usually name the class Immutable... which
reminds us all that its supposed to be immutable.

non-final classes are a design flaw (further explanation pending).
I often annotate interfaces with @Immutable to indicate that all behaviour
defined on that interface should not modify state of implementations.
Metadata in type name is a thing of the past (theoretically) and should be
avoided.
 
A

Andrew McDonagh

Tony said:
non-final classes are a design flaw (further explanation pending).

that depends upon one's view, and we all know your view you have
mentioned it often :)

Whilst I tend to prefer not to final-ise classes, i do strongly believe
in favoring delegation over inheritance - so I'm more on your side of
the fence.

I often annotate interfaces with @Immutable to indicate that all behaviour
defined on that interface should not modify state of implementations.

a good thing.
Metadata in type name is a thing of the past (theoretically) and should be
avoided.

with most metadata, yes i agree, but not with this topics discussion of
immutability.

I prefer intent revealing names to excessive (often unread) documentation.
 
D

Daniel Dyer

Basically any class is immutable , so long as there is no way of
modifying its contents after creation.

e.g immutable class .

class A {
public A(int valueToUse) {
value = valueToUse;
}


public int getValue() {
return value;
}

private int value;
}


A's int value can only be set at construction, not after.

Additionally the class should be declared final. Although a sub-class
cannot access the value member directly, it can over-ride getValue() to
return something different.

Dan.
 
D

Daniel Dyer

Whilst I tend to prefer not to final-ise classes, i do strongly believe
in favoring delegation over inheritance - so I'm more on your side of
the fence.

As an alternative to making the class final you could make all the methods
final, but I can't think of a situation in which you would really want to
extend an "immutable" class. And, as you say, delegation would probably
be preferable if there were such a situation. So is there a good reason
to not make "immutable" classes final?

Dan.
 
A

Andrew McDonagh

Daniel said:
As an alternative to making the class final you could make all the
methods final, but I can't think of a situation in which you would
really want to extend an "immutable" class. And, as you say,
delegation would probably be preferable if there were such a
situation. So is there a good reason to not make "immutable" classes
final?

Dan.

Absolutely.... As someone who uses TDD, testability is one that comes to
mind straight away.

Sometimes its useful to create a derived version of a class to aid unit
testing.


very contrived example...


public void testImmutableObject() {

TestableImmutableThing testable = new ImmutableThing(..) {

// override the method
public void doSomething() {
super.doSomething();
wasSomethingCalled = true;
}

};

testable.doSometing();

assertTrue(wasSomethingCalled);
}
 
T

tzvika.barenholz

Here's the short answer. get the book called "effective java" by a guy
called Josh Bloch. read the iterm 'favor immutability'. in fact - read
all the items :)
 
T

Tony Morris

Absolutely.... As someone who uses TDD, testability is one that comes to
mind straight away.

No wonder you have seen the light :) If only everybody did!
I still promise to formalise my claims; and they are somewhere down there
(points to Antarctica) on my priority list.
I've considered writing a Dissertation or even a book, but it's early
stages.
Right now, I'm working on JTiger.
 
A

Andrew McDonagh

Tony said:
No wonder you have seen the light :)

Yes for 2 years now.
If only everybody did!
Absolutely!

I still promise to formalise my claims;
and they are somewhere down there
(points to Antarctica) on my priority list.
I've considered writing a Dissertation or even a book, but it's early
stages.

That would be good.
Right now, I'm working on JTiger.

Just had a look, seems promising. Has is been mentioned on any of the
Agile lists? TDD tools (IMHO) tend to become popular in the agile
domains before moving into main stream.

worth a posting to the yahoo groups..

extremeprogramming, testdrivendevelopment, refactoring

and if you do write an article, agilearticles.

I suppose one of its major hurdles is Java 1.5 (5.0 what ever its
called) take up for commercial development. I know a lot of places have
started going over, but I know that a lot more are holding off.

Andrew
 
H

hiwa

Andrew said:
i do strongly believe in favoring delegation over inheritance
Could you elaborate on that? Small example codes attached would
greatly help understanding.
 
A

Andrew McDonagh

hiwa said:
Could you elaborate on that? Small example codes attached would
greatly help understanding.

Will do, let me think about a simple example and I'll get back to you....
 
A

Andrew McDonagh

hiwa said:
Could you elaborate on that? Small example codes attached would
greatly help understanding.

Ok...


Cars, great things for getting us around the place.

They come in many different types. At least 3 viable engine
technologies. Many, many different colours. Each manufacture make many
different models and each model typically has several different levels
within it.

So how would we model this?

How about a base class Car

Then maybe a manufactures car type, FordCar.

No hang on that doesn't work, Ford is brand, not a car, so the is-a
relation does not work here, but a Car has-a brand, hmm.. delegation.

Brand brand = car.getBrand();


Ok, so cars carry people, and typically have doors. 2, 4, 5.

So we could have 2DoorCar, 4DoorCar, 6Doorcar,... whilst it would allow
us to reuse code in the base class, the number of doors a car has is a
property of a car, its not a car itself.

So again, we have

Doors doors = new Door(4);
Car a4DoorCar = new Car(doors);

Door d = car.getDoors();
d.lock();

Ok, onto Model, lets take the BMW range.

there's the 1, 3, 5 series. So lets have

Car
|
BMWCar
|
--------------------
| | |
Series1 Series3 Series5

But hang on, they just realised a new model, the X5, do we really want
to change our class hierarchy to accommodate the new model, we'll have
to rebuild every thing and redeploy.

Or...

Model m = new Model("X5");

Car beemer = new Car(Brand, Model, doors);

beemer.getDoors().lock();
beemer.getBrand().isLuxuryBrand();
beemer.getModel().canGoOffRoad();

What I'm trying to show, is that by using delegation rather than
inheritance, we have a dynamic relationship rather than a static
relationship. Meaning the user can create all sorts of relationships at
runtime, without us having to hardcode anything.

A car has-a description (Brand, Model, Engine, Colour etc).

A car isn't aBmwSeries3TwoLitreBlackEtc.

HTH

Andrew
 
T

Tony Morris

Andrew McDonagh said:
Yes for 2 years now.


That would be good.


Just had a look, seems promising. Has is been mentioned on any of the
Agile lists? TDD tools (IMHO) tend to become popular in the agile
domains before moving into main stream.

worth a posting to the yahoo groups..

extremeprogramming, testdrivendevelopment, refactoring

and if you do write an article, agilearticles.

I suppose one of its major hurdles is Java 1.5 (5.0 what ever its
called) take up for commercial development. I know a lot of places have
started going over, but I know that a lot more are holding off.

Andrew

I get hits from testdriven.com but I can't quite figure out which page
exactly (and I haven't really tried).
I'm hoping to write an article on IBM DeveloperWorks some time soon.
I'll look into the other places that you mention.
Agreed - 1.5 is the hurdle, but I'm sticking with it in the hope that the
unsubstantiated fear (which is what a lot of it is) subsides.
I have had one major issue with a 1.5 bug (and several minor issues that
clients will never know about):
http://forum.jtiger.org/posts/list/24.page
 
H

hiwa

Thanks Andrew for a clear-cut and entertaining explanation.

I have begun to feel that object delegation and class inheritance
are not well compatible nor well complementary each other.

Should class be antiquated in next few decades?
Should it be a useless loner, and disturbance for a better dynamic
mapping between code and reality, called next generation programming
language?

I'd like to study further on this subject.

Thanks again.
 
P

P.Hill

Andrew said:
beemer.getDoors().lock();
beemer.getBrand().isLuxuryBrand();
beemer.getModel().canGoOffRoad();

Except that you now bordering on promoting excessive
interpendancies in which a user of a Car object now
needs to know about Car, Door, Brand, Model, Wheels etc. objects.
This would be a terrible problem if unmanaged.
Sure "inject" some object and delegate to the object, but
you can't make the caller do a.b.c.d.getName() to get at a
everybit of information.

Which objects delegated to the containing object and which
are exposed for the caller to use directly can be the art of
designing a good object system.

-Paul
 
A

Andrew McDonagh

P.Hill said:
Except that you now bordering on promoting excessive
interpendancies in which a user of a Car object now
needs to know about Car, Door, Brand, Model, Wheels etc. objects.
This would be a terrible problem if unmanaged.
Sure "inject" some object and delegate to the object, but
you can't make the caller do a.b.c.d.getName() to get at a
everybit of information.

Which objects delegated to the containing object and which
are exposed for the caller to use directly can be the art of
designing a good object system.

-Paul

Absolutely, it is only an example.

if I was doing this for real, then a Car object would normally take a
Description object as its sole parameter.

Then back into example world, depending upon how many atomic parts make
up a description, I may remove the need to provide getName() etc,
methods at all, and reverse the dependency so that Description can visit
a display itself. Something like....

Car aCar = new Car(description);

DescriptionDialog displayCarDetails = new CarDetailsDialog(CarDescripton
description) {
description.initialiseMe(this);
}

displaycarDetails.showDialog();

But this last bit is an example and a pinch of salt is needed to weigh
it against your very true statement about balancing being an art.

Description may in fact be a simplish holder of just a few parts.

class CarDescription {
ModelDetails modelDescription;
EngineDetails engineDescription
TrimLevelDescription trimLevelDescription;
PriceRangeDescription priceRangeDescription;
}

Inside each sub description is where we could have the actual deatils...
 
A

Andrew McDonagh

hiwa said:
Thanks Andrew for a clear-cut and entertaining explanation.

I have begun to feel that object delegation and class inheritance
are not well compatible nor well complementary each other.

Ooops maybe I pushed the delegation part too far and neglected the
inheritance part then. Inheritance plays an important part in OO, and
the two play well together.

The skill comes (with time) in being able to see when to use either of
the relationship types. Using either one all of the time, at the expense
of the other, tends to result in a design that is less than optimal.

If we always use inheritance rather than a mixture, we'll have a very
ridged statically modeled design. If we always use delegation rather
than a mixture, we'll have a flexible but difficult to complicated design.

IMHO, one of the hardest habits to get into when choosing to delegate or
inherit, is to ask yourself, this class I have 'is it a' thingy, or does
it 'have a' or 'uses a' thingy.

Sounds trivial when stated like this, but sometimes one way will feel
very natural, but will be wrong, as in the Brand <-> Car relationship I
showed.

It certainly seems natural to have a FordCar, BMWCar, etc. but then we
ask ourselves, this Car 'is it' a Ford, BMW, etc, or does it 'have a'
Brand which happens to be Ford, BMW, etc.

Sometimes, it comes down to the application you are creating. If its a
Car dealership app for dealerships that only sell Ford and BMWs, we
could use inheritance as the requirements are pretty static. But then
what happens when they release they are missing a market which VW would
naturally fit in and therefore start to sell VW cars. Do we have to
re-write or upgrade the app, or does it already support the ability to
handle the new Brand of cars?

Should class be antiquated in next few decades?

No, so long as we use OO, we'll have classes.
Should it be a useless loner, and disturbance for a better dynamic
mapping between code and reality, called next generation programming
language?

There's every chance that in a few year time, a new programming paradigm
will emerge that we start to use en mass instead of OO, what its called
I don't know.
I'd like to study further on this subject.

We all do :)

I've been OOing for 6 years and I'm still learning.

com.object is a good newsgroup for discussing general OO topics, it
would be worth subscribing to it and don't be afraid to ask for help.
Thanks again.

No problems.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top