How can I ensure thread-safety of a java bean with multiple setters? I've got a User object with about 20 properties and I feel it would be impractical to pass all values in via the constructor also because of that not all values are compulsory.
You might want to look at Joshua Bloch's Builder pattern (a specific adaptation of the GoF Builder), discussed in Effective Java, 2nd Edition. You can also find a short version here on p. 7-10 of the PDF. Also places like here and here. One thing that none of these links really discuss is that to be properly immutable in a multithreaded environment, you need the variables in the immutable class to be final. So you do something like this:
Here X, y, z are all required, and a, b, c are optional. Use it like this:
Other variants are possible. If you have a lot of required parameters, you may want to use named methods to assign them too, rather than a constructor. In this case, you won't be able to get the compiler to ensure that all required values have been set - but you can add a runtime validator to throw an exception instead. You can also add more complex validation that's not possible to enforce at compile time.
Incidentally, at my workplace we use a lot of self-returning methods (like the methods that "return this" above), and we tend to format the method call chains with one line per method, like this:
I find that can lead to very readable code for construction of objects with many parameters. Using "with" here is just a local convention we have - the Bloch equivalent code would omit that. [ August 13, 2008: Message edited by: Mike Simmons ]
It would be interesting to know how your User object is being used. Mike's solution makes your class immutable which is always good. But does your use case require that one instance be open to modification by multiple threads ?
Joined: Jul 11, 2001
An alternative to the Build pattern would be to use a Parameter Object for the constructor. That parameter object could have all the setters and probably didn't need to be thread safe. (Using a parameter object in this way has a more specific design pattern name that I can't currently remember...)
The soul is dyed the color of its thoughts. Think only on those things that are in line with your principles and can bear the light of day. The content of your character is your choice. Day by day, what you do is who you become. Your integrity is your destiny - it is the light that guides your way. - Heraclitus