This week's book giveaway is in the Other Languages forum.
We're giving away four copies of Functional Reactive Programming and have Stephen Blackheath and Anthony Jones on-line!
See this thread for details.
Win a copy of Functional Reactive Programming this week in the Other Languages forum!
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic

An immutable class using a public no-args constructor

 
Dean Pullen
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi all,

I'm trying to implement an immutable class, and am using the static builder pattern as defined in Effective Java.

i.e. http://my.safaribooksonline.com/book/programming/java/9780137150021/creating-and-destroying-objects/ch02lev1sec2

This is a usual pattern I follow. However, I'm constrained by a third party system that requires an instance of the object to be initialised via a no-args public constructor.
It will then be 'properly' initialised by a (non-static) builder at the appropriate place.

What do people think of allowing this? It seems dirty but can't quite put my finger on how dirty!

Cheers,

Dean

 
Jesper de Jong
Java Cowboy
Saloon Keeper
Posts: 15490
43
Android IntelliJ IDE Java Scala Spring
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
The builder pattern is good. If there's no way around having a public no-args constructor for that third-party system, then at least describe in the Javadoc documentation for that constructor why it's there, that it's only purpose is to be used by the third-party system, and that developers should not use it directly.

You could also invent a solution where you let the third-party system not initialize your immutable object itself, but another intermediary object, and then you create your immutable object from that when the third-party system has done its job. That would however make your software more complex, so you'd have to decide if it's worth the trouble, and depending on the details of how everything works it might not even be possible.
 
drac yang
Ranch Hand
Posts: 75
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
if the immutable class is being implemented, i.e. hasn't been implemented yet, why does the third party system have already decided to construct it according to its own way, not according to your supplied instantiating way. it's supposed to use your class by its existing layout, i think it's a design issue.
 
Jayesh A Lalwani
Rancher
Posts: 2756
32
Eclipse IDE Spring Tomcat Server
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
This is common for frameworks that use reflection to initialize objects. They expect the object to have a non-args constructor, and have setter methods for the properties. The framework reads a configuration file that describes which class to instantiate and which properties to set. A very common example is java.util.logging. For the most part Logger should be immutable, but it's not. You should use the static builder to get a logger, and then use it to log. The static builder reads the logging properties and initializes the logger object. Most applications don't change the logging properties at runtime. However, the reason logger is not made immutable is because the static builder itself needs setter methods

The way I approach a problem like this is by having an immutable interface. For the most part, you want immutability because you want to delineate the code:- This factory module is responsible for initializing the object. All these other modules use the object but don't modify it. So, what I do is introduce an interface with only getter methods. All the modules that use the object are coded to the immutable interface. The actual implementation itself is mutable. The factory itself knows the concrete class and knows knows that the concrete class is mutable, and it takes advantage of mutability of the object to initialize it.
 
Winston Gutkowski
Bartender
Pie
Posts: 10527
64
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Jayesh A Lalwani wrote:For the most part Logger should be immutable, but it's not. You should use the static builder to get a logger, and then use it to log. The static builder reads the logging properties and initializes the logger object. Most applications don't change the logging properties at runtime. However, the reason logger is not made immutable is because the static builder itself needs setter methods.

Surely that doesn't stop the Logger class itself from being immutable?

I use Builders quite a lot when I've got complex objects, but it doesn't stop the object itself from being immutable after I've run build().

But I'm not familiar with Logger, so I may be missing something.

Winston
 
Jayesh A Lalwani
Rancher
Posts: 2756
32
Eclipse IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
java.util.logging.Logger is mutable. The API allows the application to change logging levels and add and remove handlers at run time, although it really shouldn't. IMO, it should have been an immutable interface rather than an object.
 
Dean Pullen
Ranch Hand
Posts: 58
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Cheers for the feedback everyone
 
  • Post Reply
  • Bookmark Topic Watch Topic
  • New Topic