To start using Immutables, all you need to do is to add it to your dependencies. For example with Maven project you will have:
IDE configuration
Let's see what should be done in IntelliJ IDEA to make work with Immutables easier. First we need to make sure that Annotation Processors are enabled for your project. To do this go to File > Settings > Build, Execution, Deployment > Compiler > Annotation Processors and select your module/project where you want to enable annotation processing:"Enable annotation processing" checkbox should be checked together with "Obtain annotation processors from project classpath" option (like on the screenshot above). If they are not selected - click them and save the config. After this generated classes will appear in target subfolder. To make them visible to you in the IDE open module settings:
Select your module, and make sure that folder that contains your generated code is marked as "Sources" and "Exclude" is removed from that folder (in our case it's target/generated-sources/annotations). If you don't do this - your project will compile and work fine with Maven but not in the IDE, as generated stuff will not be visible to it.
For Eclipse configuration you can see the documentation here.
Creating value objects
Finally! Let's start creating immutable value objects. For purposes of this post we will consider a Book value object example. We will have a Book written by the Author and identified by ISBN number. Let's start with the Author:So we see that all we need to do is define an abstract accessors to properties that we'd like our object to have and mark the class itself with @Value.Immutable. After doing this you can build the project and implementation will be generated for you, so you can start using Author objects:
You can see how builder is generated by Immutables. By default Immutables will make sure that passed values are not null:
But what if you need more validations applied? It's possible by adding check methods annotated with @Value.Check. Let's take a look at ISBN to show this: So we created another abstract class and added check method annotated with @Value.Check, which contains different kinds of checks for ISBN number. We used AssertJ Precondition methods to make a couple of checks for number validity. Note that these checks will run when you will try to construct an object - so no invalid objects should be present in your application.
Now let's combine our ISBN and Author into a Book and perform some simple manipulations on the book instance.
As you see immutable objects can be built not only from abstract classes but from interfaces as well. Generated classes also have some methods to create new objects from your immutables. Let's see some simple examples:
So we see that using Immutables allows us to save some time, as we don't need to write builders, over and over again, for each immutable object that we add, and we don't need to have properties and huge constructors, but just a list of accessor methods.
All the code from this post can be found on GitHub.
To be continued...
COMMENTS