SlideShare ist ein Scribd-Unternehmen logo
1 von 143
www.marcus-biel.com
MARCUS BIEL,Software Craftsman
Immutables in Java
The concept of Immutability has always been very important
across all programming languages.
MARCUS BIEL,Software Craftsman
Immutables in Java
MARCUS BIEL,Software Craftsman
Immutables in Java
For a Java developer however, Immutable classes,
or simply, "Immutables",
MARCUS BIEL,Software Craftsman
Immutables in Java
have become more important than ever with the release of Java 8.
MARCUS BIEL,Software Craftsman
Immutables in Java
Among many other cool things,
this version introduced the concept of
functional programming as well as the new java.time api.
MARCUS BIEL,Software Craftsman
Immutables in Java
Immutable classes play a key role
in both of these new features.
MARCUS BIEL,Software Craftsman
Immutables in Java
Because of this,
I’ve decided to provide you with
a detailed look at Immutables.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Outline
•What is an Immutable?
• Advantages & disadvantages
• How to create an Immutable
• When to use Immutables
I'll tell you exactly what an Immutable is,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Outline
• What is an Immutable?
•Advantages & disadvantages
• How to create an Immutable
• When to use Immutables
its advantages and disadvantages,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Outline
• What is an Immutable?
• Advantages & disadvantages
•How to create an Immutable
• When to use Immutables
and how to create an Immutable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Outline
• What is an Immutable?
• Advantages & disadvantages
• How to create an Immutable
•When to use Immutables
I’ll finish by giving you concrete advice on
when to use Immutables in your daily work.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
•What is an Immutable?
• Advantages & disadvantages
• How to create an Immutable
• When to use Immutables
So let’s start with the most important question –
what is an Immutable class?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
In short,
an Immutable class is a class whose instances
cannot be modified.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
The information contained in each immutable object
is provided when it is created -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
and is frozen for its lifetime.
Once an Immutable object has been created,
it is read only, forever fixed, like a fossil.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
USS Enterprise (NCC-1701)
ImmutableSpaceship enterprise = new ImmutableSpaceship("Enterprise");
enterprise.exploreGalaxy();
So if an object is immutable, how can we modify it?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
What is an Immutable?
USS Enterprise (NCC-1701)
ImmutableSpaceship enterprise = new ImmutableSpaceship("Enterprise");
enterprise.exploreGalaxy();
How can we change this unchangeable spaceship?
How can we explore strange new worlds and
“boldly go where no man has gone before”?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
What is an Immutable?
As it turns out, we can’t. As I've said,
you cannot change an Immutable.
Instead, you can return a new
Object that does reflect the change.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
What is an Immutable?
In this case we’d return a new
ImmutableSpaceship object with
a new Destination value of “OUTER_SPACE”.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Outline
• What is an Immutable?
•Advantages & disadvantages
• How to create an Immutable
• When to use Immutables
So far this seems useless.
Why should you bother with Immutables?
What kind of advantages will they bring you?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Advantages of Immutables
• Are stable & fault tolerant
First of all, Immutable classes greatly reduce the
effort needed to implement a stable
and fault tolerant system.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Advantages of Immutables
• Are stable & fault tolerant
After object creation,
Immutables can be in only one state,
which seems very confining at first,
but it’s actually extremely beneficial. Let’s see why.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
Imagine we have to
implement a bank's accounting software.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
As a result of the financial crisis,
the bank doesn't want its customers to be in debt.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
In other words,
there is a business rule that
an account balance must never be negative.
Such a rule is called an invariant.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
private void validate(long balance) {
if (balance < 0) {
throw new IllegalArgumentException("balance must not be negative:"+ balance);
}
}
To implement this rule,
we will add a validation method that gets called
whenever the balance is changed.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
private void validate(long balance) {
if (balance < 0) {
throw new IllegalArgumentException("balance must not be negative:"+ balance);
}
}
Immutables are stable & fault tolerant
In case of an attempt to overdraw the account,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
private void validate(long balance) {
if (balance < 0) {
throw new IllegalArgumentException("balance must not be negative:"+ balance);
}
}
an IllegalArgumentException will be thrown.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
As you probably can imagine,
the bank wants us to implement
a variety of functions for their clients,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
for example
withdraw(), payDebt() and
transferMoney().
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
To enforce the rule that the account’s
balance must never be negative,
we have to call the validation method from all these methods.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
This seems like a lot of duplicated code.
There must be a better way!
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
Pause here and think of an
alternative way to make sure
that none of these methods would
overdraw the account’s balance.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
Okay, the truth is, I tricked you a bit.
We don't actually need to validate the balance in each method.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
I said we need to validate the object whenever it is changing,
but an Immutable is not changing.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
Immutables are stable & fault tolerant
Instead, we validate the balance once in the constructor,
so that no invalid object can be constructed.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
Once validated,
an immutable object will stay valid for its entire lifetime.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
} WOW! This is really cool!
Methods like withdraw(), payDebt() and transferMoney()
will return a new object, which will again call
the constructor and validate the new balance.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {…}
public ImmutableAccount payDebt(long amount) {…}
public ImmutableAccount transferMoney(long amount) {…}
[…]
}
Immutables are stable & fault tolerant
But wait, it gets even better!
An Immutable remains consistent –
even in the case of an exception.
Let me give you an example:
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
Imagine you go to the ATM -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
- to get some cash.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
You put in your bank card, you type in your PIN.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
The bank takes the money …
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
out of your account.
But just before it gets into your hands,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
there’s an issue with the ATM.
The money has already been taken out of your bank account,
but it isn’t coming out of the machine.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
So now, you can kiss your money good bye.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
Unless the account has been implemented as an
Immutable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
In this case, your balance will be in the same state
that it was before the failure occurred.
Let’s see what this looks like in code.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
}
[…]
}
Immutables are stable & fault tolerant
If we are trying to withdraw money from our
ImmutableAccount class,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables are stable & fault tolerant
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
and an exception occurs,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
Immutables are stable & fault tolerant
a new ImmutableAccount object will never be created and
the original bank account object will
stay unchanged and be saved.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
Immutables are stable & fault tolerant
So as I’ve shown you,
an Immutable object can never get into an inconsistent state,
even in the case of an exception.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
Immutables are stable & fault tolerant
This stability comes at no cost,
apart from the cost of the initial validation.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
Immutables are stable & fault tolerant
It's based on the simple fact that
an Immutable cannot change after object creation.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableAccount {
private final long balance;
public ImmutableAccount(long balance) {
validate(balance);
this.balance = balance;
}
public ImmutableAccount withdraw(long amount) {
long newBalance = newBalance(amount);
return new ImmutableAccount(newBalance);
}
private long newBalance(long amount) {
// exception during balance calculation
}
[…]
}
Immutables are stable & fault tolerant
Ok, I hope you haven't fallen asleep yet.
There is so much more that Immutables have to offer,
so let’s go on.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
• Are stable & fault tolerant
• Can be shared freely
Since Immutables don’t change,
they can be shared freely. Let’s see what this means.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
Balance
AccountAccount
Holder HolderBalance
In this example,
two Mutable Account objects are
sharing the same Balance attribute.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
AccountAccount
Holder HolderBalance
If the Account object on the right
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
AccountAccount
Holder HolderBalance
changes the balance,
this will also indirectly influence the Account object on the left.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
AccountAccount
Holder HolderBalance
If, however, the balance attribute is immutable,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Holder
Account
Immutables can be shared freely
Account
Holder
Balan
ce
Balance
when the Account object on the right tries to
change the balance object, it will not change,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Account
Balance Holder
Immutables can be shared freely
Account
Holder Balance
but return a new object instead.
So there will be a second balance object now.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Account
Balance Holder
Immutables can be shared freely
Account
Holder Balance
For the same reason - an Immutable does not need a
copy constructor when copying an object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
If you don’t understand what this means or
you’d like to learn more about
cloning and copy constructors,
check out my video “Shallow versus Deep Copy”.
http://www.marcus-biel.com/shallow-vs-deep-copy-video-tutorial/
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
• Are stable & fault tolerant
• Can be shared freely
Immutables can even be shared freely,
when using a lock free algorithm in
a multithreaded environment,
where multiple actions happen in parallel.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables can be shared freely
• Are stable & fault tolerant
• Can be shared freely
Many see this as the key benefit of Immutables.
However, it is a very advanced subject,
so I won't go into detail here,
but will probably show it at a later stage.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables work well as Map keys and Set elements
• Are stable & fault tolerant
• Can be shared freely
• Work well as Map keys and Set elements
Finally, Immutable objects are also a perfect option
to use as Map keys and Set elements,
since Map keys and Set elements must never change.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables work well as Map keys and Set elements
These are the main advantages of Immutables.
Let’s also look at their disadvantages.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Disadvantages of Immutables
• May lead to performance problems
The biggest disadvantage of Immutable classes is that
their use may lead to performance problems.
Let's see how.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables may lead to performance problems
Object
Immutables require a new object
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables may lead to performance problems
for every distinct state they represent.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables may lead to performance problems
Therefore, the use of Immutables often
increases the number of objects created.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables may lead to performance problems
Naturally, the more objects that are created,
the more system resources will be used.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Immutables may lead to performance problems
However, this may not be a problem at all.
There are many more influencing factors
as we will see later on.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
How to create an Immutable
• What is an Immutable?
• Advantages & disadvantages
•How to create an Immutable
• When to use Immutables
So now that I’ve shown the value of an Immutable class.
How can we actually make one?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
How to create an Immutable
• What is an Immutable?
• Advantages & disadvantages
•How to create an Immutable
• When to use Immutables
To make a class immutable,
we have to follow a few rules:
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
1. Make all attributes private final.
First of all,
we have to make all its attributes private and final
Copyright © 2016 Marcus Bielwww.marcus-biel.com
private final String name;
private final Destination destination;
1. Make all attributes private final
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
Let’s illustrate this by looking at the
ImmutableSpaceship class I introduced you to before.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
private final String name;
private final Destination destination;
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
We make the attributes private,
so that no reference can be accessed from outside.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
private final String name;
private final Destination destination;
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
While private variables cannot be
accessed from outside the class,
they can still be reassigned.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
private final String name;
private final Destination destination;
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
To prevent this we also have to make all variables final.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
private final String name;
private final Destination destination;
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
Setting all internal reference variables to final –
clearly communicates our intent to make an immutable class.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
1. Make all attributes private final
private final String name;
private final Destination destination;
public final class ImmutableSpaceship {
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
}
Should someone try to reassign a reference variable,
a compiler error will occur.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
2. Don’t provide any methods that modify the object’s state
1. Make all attributes private and final.
2. Don’t provide any methods that modify the
object’s state.
Okay. Second,
we must not provide any methods
that modify the object’s state.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
2. Don’t provide any methods that modify the object’s state
1. Make all attributes private and final.
2. Don’t provide any methods that modify the
object’s state.
This I have already briefly discussed
at the beginning of this presentation,
but now we will look at it more closely.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
2. Don’t provide any methods that modify the object’s state
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
For any change that you want to apply
to your Immutable object,
you have to provide a method that returns a new object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
2. Don’t provide any methods that modify the object’s state
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
Attributes that do not change, like “name” in this case,
can be copied from our current object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
2. Don’t provide any methods that modify the object’s state
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
Attributes that do change, like “destination” in this case,
have to be initialized with a new value instead.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
3. Ensure that the class can’t be extended
1. Make all attributes private and final.
2. Don’t provide any methods that modify the
object’s state.
3. Ensure that the class can’t be extended.
Let’s go on to the next rule.
To further protect our class from being changed,
we also have to prevent it from being extended.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
3. Ensure that the class can’t be extended
1. Make all attributes private and final.
2. Don’t provide any methods that modify the
object’s state.
3. Ensure that the class can’t be extended.
Extending a class would allow you to override its methods.
This would allow you to directly change the
“unchangeable" object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
3. Ensure that the class can’t be extended
1. Make all attributes private and final.
2. Don’t provide any methods that modify the
object’s state.
3. Ensure that the class can’t be extended.
Let's look at a code example to better illustrate this:
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public class RomulanSpaceship extends ImmutableSpaceship {
@Override
public RomulanSpaceship exploreGalaxy() {
this.destination = Destination.OUTER_SPACE;
return this;
}
3. Ensure that the class can’t be extended
[…]
}
private String name;
private Destination destination;
public RomulanSpaceship(String name) {
super(name);
}
So here we have a RomulanSpaceship
extending our ImmutableSpaceship.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
@Override
public RomulanSpaceship exploreGalaxy() {
this.destination = Destination.NEUTRAL_ZONE;
return this;
}
public class RomulanSpaceship extends ImmutableSpaceship {
3. Ensure that the class can’t be extended
[…]
}
private String name;
private Destination destination;
public RomulanSpaceship(String name) {
super(name);
}
Its overridden exploreGalaxy() method
violates the rules of an Immutable,
as it directly changes the destination attribute.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen");
3. Ensure that the class can’t be extended
As RomulanSpaceship extends ImmutableSpaceship
Copyright © 2016 Marcus Bielwww.marcus-biel.com
3. Ensure that the class can’t be extended
ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen");
we can create an instance of a RomulanSpaceship,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
3. Ensure that the class can’t be extended
ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen");
and assign it to an ImmutableSpaceship
reference variable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen");
[…]
immutableSpaceship.exploreGalaxy(); // internally changes the "immutable" Spaceship
3. Ensure that the class can’t be extended
Much later in the code, in a different class and method,
we will call the exploreGalaxy() method
on our ImmutableSpaceship instance -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen");
[…]
immutableSpaceship.exploreGalaxy(); // internally changes the "immutable" Spaceship
3. Ensure that the class can’t be extended
which, much to our concern,
will internally change the spaceship instance,
which we expected to be unchangeable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public final class ImmutableSpaceship {
3. Ensure that the class can’t be extended
private final String name;
private final Destination destination;
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = Destination.NONE;
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
public ImmutableSpaceship exploreGalaxy() {
return new ImmutableSpaceship(name, Destination.OUTER_SPACE);
}
[…]
} To prevent this, we just have to make our class final.
A final class can’t be extended,
so it won’t be possible to override any method either.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
1. Make all attributes private and final.
2. Don’t provide any methods that modify the object’s
state.
3. Ensure that the class can’t be extended.
4. Ensure exclusive access to any mutable attributes.
And now to the final rule –
we have ensure exclusive access to any mutable attributes.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Here you can see a
representation of our spaceship object.
Name
Spaceship
DestinationName
Immutable
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
The attribute “name” is of type String,
which is an Immutable.
Name
Spaceship
DestinationName
Immutable
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
As I've already shown you,
you can freely share Immutable attributes -
Name
Spaceship
DestinationName
Immutable
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Name
Spaceship
DestinationName
Immutable
Mutable
with other objects, as they cannot be changed.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
The Destination object, in this case,
we’ll assume, is Mutable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
Mutable
Anyone who holds a reference to it -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
Mutable
can alter it.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Immutable
Mutable
This will effectively alter our "Immutable" object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
Mutable
4. Ensure exclusive access to any mutable attributes
In other words, it would not be immutable.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Mutable
So to protect our Immutable object -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Mutable
Spaceship
DestinationName
Immutable
we have to isolate the mutable destination attribute from
the outside and prevent anyone from getting hold of it.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
Destination
Mutable
To achieve this, we never obtain or
return a direct reference to a destination object.
Instead we create a deep copy and work with that instead.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
DestinationDestination
Mutable
As long as the mutable destination object
is never directly shared,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
DestinationDestination
Mutable
a change inside an external object will not
have any effect on our immutable object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
Spaceship
DestinationName
Immutable
DestinationDestination
Mutable
Okay, talk is cheap, show me the code.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
4. Ensure exclusive access to any mutable attributes
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
To ensure exclusive access to
our mutable destination attribute,
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
we have to check all public methods and
constructors for any
incoming or outgoing Destination references.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
Let’s do this now.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
The public constructor does not
receive any Destination reference.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
The Destination object it creates is safe,
as it cannot be accessed from outside.
So the public constructor is good as it is.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
The public currentDestination()
method returns a reference -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return destination;
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
to our internal Destination object, so this must be fixed.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
Now, instead of returning the real
reference we create a deep copy
of our Destination object and return
a reference to the copy instead.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
Finally,
the public newDestination() method receives -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
a Destination reference -
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
and forwards this reference to our private constructor.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
Now the private constructor directly stores the
mutable Destination reference it receives.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
So, by following the execution path,
we found that it is directly stored in the private constructor.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = destination;
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
This must not be allowed.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
4. Ensure exclusive access to any mutable attributes
public ImmutableSpaceship newDestination(Destination newDestination) {
return new ImmutableSpaceship(this.name, newDestination);
}
public Destination currentDestination() {
return new Destination(destination);
}
public ImmutableSpaceship(String name) {
this.name = name;
this.destination = new Destination("NONE");
}
private ImmutableSpaceship(String name, Destination destination) {
this.name = name;
this.destination = new Destination(destination);
}
[…]
}
public final class ImmutableSpaceship {
private final String name;
private final Destination destination;
To stop it immediately,
we store a reference to a deep copy
of the external Destination object.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
• What is an Immutable?
• Advantages & disadvantages
• How to create an Immutable
•When to use Immutables
Okay. So I've shown you what an Immutable is,
I've told you about its advantages and disadvantages,
and finally, I have demonstrated
how to create an Immutable class.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
There is just one last thing I would like
to tell you –
When should YOU actually use an
Immutable class in your code?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
The question of whether you should
design a specific class as an Immutable
depends mainly on whether the
performance of the overall system is
sufficient or not.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
This again depends on the nature of the
system and all aspects related to it.
For example: What kind of specific
problem are you trying to solve?
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
On what kind of hardware is your
program running? Is it a desktop or
web application? It also depends on
the internal structure of your code.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
For example: Of how many packages,
classes and methods does your code
consist of? As you can see, there is no
simple answer to this very complex
question.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
Each case must be looked at
individually.
As a general recommendation however,
I advise you to follow this approach:
Focus on designing a system that uses
immutables to the greatest possible
extent.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
Facilitate their use by designing simple
classes with few attributes and
methods.
Immutables may become a burden
when they are too complex.
Simplicity is key.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
In this endeavor, Clean Code and
Immutables are a well matched pair,
reinforcing each other.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
In the majority of cases,
this approach will lead to a system that
exceeds all requirements.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
If however, testing reveals that
you have not achieved satisfactory
performance, relax the immutability
rules gradually.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
As much as necessary,
but as little as possible.
Copyright © 2016 Marcus Bielwww.marcus-biel.com
When to use Immutables
Copyright © 2016
Marcus Biel
All rights reserved.

Weitere ähnliche Inhalte

Andere mochten auch

Andere mochten auch (10)

Java Comparable Interface Video Tutorial
Java Comparable Interface Video Tutorial Java Comparable Interface Video Tutorial
Java Comparable Interface Video Tutorial
 
Կենդանական օրգանիզմի հյուսվածքները
Կենդանական օրգանիզմի հյուսվածքներըԿենդանական օրգանիզմի հյուսվածքները
Կենդանական օրգանիզմի հյուսվածքները
 
A bolsa amarela
A bolsa amarelaA bolsa amarela
A bolsa amarela
 
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time APIModern Programming in Java 8 - Lambdas, Streams and Date Time API
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
 
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
Java 9 and the impact on Maven Projects (ApacheCon Europe 2016)
 
Graphs data Structure
Graphs data StructureGraphs data Structure
Graphs data Structure
 
Security enforcement of Java Microservices with Apiman & Keycloak
Security enforcement of Java Microservices with Apiman & KeycloakSecurity enforcement of Java Microservices with Apiman & Keycloak
Security enforcement of Java Microservices with Apiman & Keycloak
 
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
A Visual Introduction to Event Sourcing and CQRS by Lorenzo NicoraA Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
A Visual Introduction to Event Sourcing and CQRS by Lorenzo Nicora
 
Keo (novembre 2016)
Keo (novembre 2016)Keo (novembre 2016)
Keo (novembre 2016)
 
A Microservice Journey
A Microservice JourneyA Microservice Journey
A Microservice Journey
 

Ähnlich wie Immutable Classes in Java

AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
Miklos Csere
 
Asynchronous Services – A promising future for OSGi - T Ward
Asynchronous Services – A promising future for OSGi - T WardAsynchronous Services – A promising future for OSGi - T Ward
Asynchronous Services – A promising future for OSGi - T Ward
mfrancis
 
Top ten secret weapons for performance testing in an agile environment
Top ten secret weapons for performance testing in an agile environmentTop ten secret weapons for performance testing in an agile environment
Top ten secret weapons for performance testing in an agile environment
alistairjones
 

Ähnlich wie Immutable Classes in Java (20)

You Build It, But How Are You Going to Run It?
You Build It, But How Are You Going to Run It? You Build It, But How Are You Going to Run It?
You Build It, But How Are You Going to Run It?
 
Orchestration: Fancy Buzzword, or the Inevitable fate of Docker Containers?
Orchestration: Fancy Buzzword, or the Inevitable fate of Docker Containers?Orchestration: Fancy Buzzword, or the Inevitable fate of Docker Containers?
Orchestration: Fancy Buzzword, or the Inevitable fate of Docker Containers?
 
SolidWorks Design Automation Using the SolidWorks API, Microsoft Excel and VBA
SolidWorks Design Automation Using the SolidWorks API, Microsoft Excel and VBASolidWorks Design Automation Using the SolidWorks API, Microsoft Excel and VBA
SolidWorks Design Automation Using the SolidWorks API, Microsoft Excel and VBA
 
Reaching for Your Quality Stretch Goals: Testing at Realtor.com
Reaching for Your Quality Stretch Goals: Testing at Realtor.comReaching for Your Quality Stretch Goals: Testing at Realtor.com
Reaching for Your Quality Stretch Goals: Testing at Realtor.com
 
QCon London: Low latency Java in the real world - LMAX Exchange and the Zing JVM
QCon London: Low latency Java in the real world - LMAX Exchange and the Zing JVMQCon London: Low latency Java in the real world - LMAX Exchange and the Zing JVM
QCon London: Low latency Java in the real world - LMAX Exchange and the Zing JVM
 
T# @ Agile Tour Montreal 2009 En
T# @ Agile Tour Montreal 2009 EnT# @ Agile Tour Montreal 2009 En
T# @ Agile Tour Montreal 2009 En
 
Abusing the Cloud for Fun and Profit
Abusing the Cloud for Fun and ProfitAbusing the Cloud for Fun and Profit
Abusing the Cloud for Fun and Profit
 
Scalability vs elasticity
Scalability vs elasticityScalability vs elasticity
Scalability vs elasticity
 
AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere AEM Clean Code - Miklos Csere
AEM Clean Code - Miklos Csere
 
The Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To KnowThe Ember.js Framework - Everything You Need To Know
The Ember.js Framework - Everything You Need To Know
 
Vertafore: Database Evaluation - Selecting Apache Cassandra
Vertafore: Database Evaluation - Selecting Apache CassandraVertafore: Database Evaluation - Selecting Apache Cassandra
Vertafore: Database Evaluation - Selecting Apache Cassandra
 
Asynchronous Services – A promising future for OSGi - T Ward
Asynchronous Services – A promising future for OSGi - T WardAsynchronous Services – A promising future for OSGi - T Ward
Asynchronous Services – A promising future for OSGi - T Ward
 
Vertical Recommendation Using Collaborative Filtering
Vertical Recommendation Using Collaborative FilteringVertical Recommendation Using Collaborative Filtering
Vertical Recommendation Using Collaborative Filtering
 
(Minimum) Enterprise Viable Product - a relook
(Minimum) Enterprise Viable Product - a relook(Minimum) Enterprise Viable Product - a relook
(Minimum) Enterprise Viable Product - a relook
 
Making everything better with OSGi - a happy case study in building a really ...
Making everything better with OSGi - a happy case study in building a really ...Making everything better with OSGi - a happy case study in building a really ...
Making everything better with OSGi - a happy case study in building a really ...
 
DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?DevOps in Practice: When does "Practice" Become "Doing"?
DevOps in Practice: When does "Practice" Become "Doing"?
 
Why you should choose Angular and why you should not
Why you should choose Angular and why you should notWhy you should choose Angular and why you should not
Why you should choose Angular and why you should not
 
Executing Migrations at the Speed of Light How to Maximise Your Velocity - AW...
Executing Migrations at the Speed of Light How to Maximise Your Velocity - AW...Executing Migrations at the Speed of Light How to Maximise Your Velocity - AW...
Executing Migrations at the Speed of Light How to Maximise Your Velocity - AW...
 
Scylla Summit 2018: Meshify - A Case Study, or Petshop Seamonsters
Scylla Summit 2018: Meshify - A Case Study, or Petshop SeamonstersScylla Summit 2018: Meshify - A Case Study, or Petshop Seamonsters
Scylla Summit 2018: Meshify - A Case Study, or Petshop Seamonsters
 
Top ten secret weapons for performance testing in an agile environment
Top ten secret weapons for performance testing in an agile environmentTop ten secret weapons for performance testing in an agile environment
Top ten secret weapons for performance testing in an agile environment
 

Kürzlich hochgeladen

The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
heathfieldcps1
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
heathfieldcps1
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
kauryashika82
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
negromaestrong
 
Making and Justifying Mathematical Decisions.pdf
Making and Justifying Mathematical Decisions.pdfMaking and Justifying Mathematical Decisions.pdf
Making and Justifying Mathematical Decisions.pdf
Chris Hunter
 

Kürzlich hochgeladen (20)

Measures of Dispersion and Variability: Range, QD, AD and SD
Measures of Dispersion and Variability: Range, QD, AD and SDMeasures of Dispersion and Variability: Range, QD, AD and SD
Measures of Dispersion and Variability: Range, QD, AD and SD
 
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
TỔNG ÔN TẬP THI VÀO LỚP 10 MÔN TIẾNG ANH NĂM HỌC 2023 - 2024 CÓ ĐÁP ÁN (NGỮ Â...
 
The basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptxThe basics of sentences session 3pptx.pptx
The basics of sentences session 3pptx.pptx
 
Measures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and ModeMeasures of Central Tendency: Mean, Median and Mode
Measures of Central Tendency: Mean, Median and Mode
 
The basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptxThe basics of sentences session 2pptx copy.pptx
The basics of sentences session 2pptx copy.pptx
 
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptxINDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
INDIA QUIZ 2024 RLAC DELHI UNIVERSITY.pptx
 
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17  How to Extend Models Using Mixin ClassesMixin Classes in Odoo 17  How to Extend Models Using Mixin Classes
Mixin Classes in Odoo 17 How to Extend Models Using Mixin Classes
 
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in DelhiRussian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
Russian Escort Service in Delhi 11k Hotel Foreigner Russian Call Girls in Delhi
 
ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.ICT role in 21st century education and it's challenges.
ICT role in 21st century education and it's challenges.
 
Z Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot GraphZ Score,T Score, Percential Rank and Box Plot Graph
Z Score,T Score, Percential Rank and Box Plot Graph
 
Seal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptxSeal of Good Local Governance (SGLG) 2024Final.pptx
Seal of Good Local Governance (SGLG) 2024Final.pptx
 
Unit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptxUnit-IV- Pharma. Marketing Channels.pptx
Unit-IV- Pharma. Marketing Channels.pptx
 
psychiatric nursing HISTORY COLLECTION .docx
psychiatric  nursing HISTORY  COLLECTION  .docxpsychiatric  nursing HISTORY  COLLECTION  .docx
psychiatric nursing HISTORY COLLECTION .docx
 
On National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan FellowsOn National Teacher Day, meet the 2024-25 Kenan Fellows
On National Teacher Day, meet the 2024-25 Kenan Fellows
 
Asian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptxAsian American Pacific Islander Month DDSD 2024.pptx
Asian American Pacific Islander Month DDSD 2024.pptx
 
Making and Justifying Mathematical Decisions.pdf
Making and Justifying Mathematical Decisions.pdfMaking and Justifying Mathematical Decisions.pdf
Making and Justifying Mathematical Decisions.pdf
 
Role Of Transgenic Animal In Target Validation-1.pptx
Role Of Transgenic Animal In Target Validation-1.pptxRole Of Transgenic Animal In Target Validation-1.pptx
Role Of Transgenic Animal In Target Validation-1.pptx
 
ComPTIA Overview | Comptia Security+ Book SY0-701
ComPTIA Overview | Comptia Security+ Book SY0-701ComPTIA Overview | Comptia Security+ Book SY0-701
ComPTIA Overview | Comptia Security+ Book SY0-701
 
Application orientated numerical on hev.ppt
Application orientated numerical on hev.pptApplication orientated numerical on hev.ppt
Application orientated numerical on hev.ppt
 
Sociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning ExhibitSociology 101 Demonstration of Learning Exhibit
Sociology 101 Demonstration of Learning Exhibit
 

Immutable Classes in Java

  • 2. The concept of Immutability has always been very important across all programming languages. MARCUS BIEL,Software Craftsman Immutables in Java
  • 3. MARCUS BIEL,Software Craftsman Immutables in Java For a Java developer however, Immutable classes, or simply, "Immutables",
  • 4. MARCUS BIEL,Software Craftsman Immutables in Java have become more important than ever with the release of Java 8.
  • 5. MARCUS BIEL,Software Craftsman Immutables in Java Among many other cool things, this version introduced the concept of functional programming as well as the new java.time api.
  • 6. MARCUS BIEL,Software Craftsman Immutables in Java Immutable classes play a key role in both of these new features.
  • 7. MARCUS BIEL,Software Craftsman Immutables in Java Because of this, I’ve decided to provide you with a detailed look at Immutables.
  • 8. Copyright © 2016 Marcus Bielwww.marcus-biel.com Outline •What is an Immutable? • Advantages & disadvantages • How to create an Immutable • When to use Immutables I'll tell you exactly what an Immutable is,
  • 9. Copyright © 2016 Marcus Bielwww.marcus-biel.com Outline • What is an Immutable? •Advantages & disadvantages • How to create an Immutable • When to use Immutables its advantages and disadvantages,
  • 10. Copyright © 2016 Marcus Bielwww.marcus-biel.com Outline • What is an Immutable? • Advantages & disadvantages •How to create an Immutable • When to use Immutables and how to create an Immutable.
  • 11. Copyright © 2016 Marcus Bielwww.marcus-biel.com Outline • What is an Immutable? • Advantages & disadvantages • How to create an Immutable •When to use Immutables I’ll finish by giving you concrete advice on when to use Immutables in your daily work.
  • 12. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? •What is an Immutable? • Advantages & disadvantages • How to create an Immutable • When to use Immutables So let’s start with the most important question – what is an Immutable class?
  • 13. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? In short, an Immutable class is a class whose instances cannot be modified.
  • 14. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? The information contained in each immutable object is provided when it is created -
  • 15. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? and is frozen for its lifetime. Once an Immutable object has been created, it is read only, forever fixed, like a fossil.
  • 16. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? USS Enterprise (NCC-1701) ImmutableSpaceship enterprise = new ImmutableSpaceship("Enterprise"); enterprise.exploreGalaxy(); So if an object is immutable, how can we modify it?
  • 17. Copyright © 2016 Marcus Bielwww.marcus-biel.com What is an Immutable? USS Enterprise (NCC-1701) ImmutableSpaceship enterprise = new ImmutableSpaceship("Enterprise"); enterprise.exploreGalaxy(); How can we change this unchangeable spaceship? How can we explore strange new worlds and “boldly go where no man has gone before”?
  • 18. Copyright © 2016 Marcus Bielwww.marcus-biel.com public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } What is an Immutable? As it turns out, we can’t. As I've said, you cannot change an Immutable. Instead, you can return a new Object that does reflect the change.
  • 19. Copyright © 2016 Marcus Bielwww.marcus-biel.com public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } What is an Immutable? In this case we’d return a new ImmutableSpaceship object with a new Destination value of “OUTER_SPACE”.
  • 20. Copyright © 2016 Marcus Bielwww.marcus-biel.com Outline • What is an Immutable? •Advantages & disadvantages • How to create an Immutable • When to use Immutables So far this seems useless. Why should you bother with Immutables? What kind of advantages will they bring you?
  • 21. Copyright © 2016 Marcus Bielwww.marcus-biel.com Advantages of Immutables • Are stable & fault tolerant First of all, Immutable classes greatly reduce the effort needed to implement a stable and fault tolerant system.
  • 22. Copyright © 2016 Marcus Bielwww.marcus-biel.com Advantages of Immutables • Are stable & fault tolerant After object creation, Immutables can be in only one state, which seems very confining at first, but it’s actually extremely beneficial. Let’s see why.
  • 23. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant Imagine we have to implement a bank's accounting software.
  • 24. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant As a result of the financial crisis, the bank doesn't want its customers to be in debt.
  • 25. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant In other words, there is a business rule that an account balance must never be negative. Such a rule is called an invariant.
  • 26. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant private void validate(long balance) { if (balance < 0) { throw new IllegalArgumentException("balance must not be negative:"+ balance); } } To implement this rule, we will add a validation method that gets called whenever the balance is changed.
  • 27. Copyright © 2016 Marcus Bielwww.marcus-biel.com private void validate(long balance) { if (balance < 0) { throw new IllegalArgumentException("balance must not be negative:"+ balance); } } Immutables are stable & fault tolerant In case of an attempt to overdraw the account,
  • 28. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant private void validate(long balance) { if (balance < 0) { throw new IllegalArgumentException("balance must not be negative:"+ balance); } } an IllegalArgumentException will be thrown.
  • 29. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant As you probably can imagine, the bank wants us to implement a variety of functions for their clients,
  • 30. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant for example withdraw(), payDebt() and transferMoney().
  • 31. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } To enforce the rule that the account’s balance must never be negative, we have to call the validation method from all these methods.
  • 32. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } This seems like a lot of duplicated code. There must be a better way!
  • 33. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } Pause here and think of an alternative way to make sure that none of these methods would overdraw the account’s balance.
  • 34. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } Okay, the truth is, I tricked you a bit. We don't actually need to validate the balance in each method.
  • 35. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } I said we need to validate the object whenever it is changing, but an Immutable is not changing.
  • 36. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } Immutables are stable & fault tolerant Instead, we validate the balance once in the constructor, so that no invalid object can be constructed.
  • 37. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } Once validated, an immutable object will stay valid for its entire lifetime.
  • 38. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } WOW! This is really cool! Methods like withdraw(), payDebt() and transferMoney() will return a new object, which will again call the constructor and validate the new balance.
  • 39. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) {…} public ImmutableAccount payDebt(long amount) {…} public ImmutableAccount transferMoney(long amount) {…} […] } Immutables are stable & fault tolerant But wait, it gets even better! An Immutable remains consistent – even in the case of an exception. Let me give you an example:
  • 40. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant Imagine you go to the ATM -
  • 41. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant - to get some cash.
  • 42. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant You put in your bank card, you type in your PIN.
  • 43. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant The bank takes the money …
  • 44. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant out of your account. But just before it gets into your hands,
  • 45. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant there’s an issue with the ATM. The money has already been taken out of your bank account, but it isn’t coming out of the machine.
  • 46. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant So now, you can kiss your money good bye.
  • 47. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant Unless the account has been implemented as an Immutable.
  • 48. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant In this case, your balance will be in the same state that it was before the failure occurred. Let’s see what this looks like in code.
  • 49. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { } […] } Immutables are stable & fault tolerant If we are trying to withdraw money from our ImmutableAccount class,
  • 50. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables are stable & fault tolerant public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } and an exception occurs,
  • 51. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } Immutables are stable & fault tolerant a new ImmutableAccount object will never be created and the original bank account object will stay unchanged and be saved.
  • 52. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } Immutables are stable & fault tolerant So as I’ve shown you, an Immutable object can never get into an inconsistent state, even in the case of an exception.
  • 53. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } Immutables are stable & fault tolerant This stability comes at no cost, apart from the cost of the initial validation.
  • 54. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } Immutables are stable & fault tolerant It's based on the simple fact that an Immutable cannot change after object creation.
  • 55. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableAccount { private final long balance; public ImmutableAccount(long balance) { validate(balance); this.balance = balance; } public ImmutableAccount withdraw(long amount) { long newBalance = newBalance(amount); return new ImmutableAccount(newBalance); } private long newBalance(long amount) { // exception during balance calculation } […] } Immutables are stable & fault tolerant Ok, I hope you haven't fallen asleep yet. There is so much more that Immutables have to offer, so let’s go on.
  • 56. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely • Are stable & fault tolerant • Can be shared freely Since Immutables don’t change, they can be shared freely. Let’s see what this means.
  • 57. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely Balance AccountAccount Holder HolderBalance In this example, two Mutable Account objects are sharing the same Balance attribute.
  • 58. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely AccountAccount Holder HolderBalance If the Account object on the right
  • 59. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely AccountAccount Holder HolderBalance changes the balance, this will also indirectly influence the Account object on the left.
  • 60. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely AccountAccount Holder HolderBalance If, however, the balance attribute is immutable,
  • 61. Copyright © 2016 Marcus Bielwww.marcus-biel.com Holder Account Immutables can be shared freely Account Holder Balan ce Balance when the Account object on the right tries to change the balance object, it will not change,
  • 62. Copyright © 2016 Marcus Bielwww.marcus-biel.com Account Balance Holder Immutables can be shared freely Account Holder Balance but return a new object instead. So there will be a second balance object now.
  • 63. Copyright © 2016 Marcus Bielwww.marcus-biel.com Account Balance Holder Immutables can be shared freely Account Holder Balance For the same reason - an Immutable does not need a copy constructor when copying an object.
  • 64. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely If you don’t understand what this means or you’d like to learn more about cloning and copy constructors, check out my video “Shallow versus Deep Copy”. http://www.marcus-biel.com/shallow-vs-deep-copy-video-tutorial/
  • 65. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely • Are stable & fault tolerant • Can be shared freely Immutables can even be shared freely, when using a lock free algorithm in a multithreaded environment, where multiple actions happen in parallel.
  • 66. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables can be shared freely • Are stable & fault tolerant • Can be shared freely Many see this as the key benefit of Immutables. However, it is a very advanced subject, so I won't go into detail here, but will probably show it at a later stage.
  • 67. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables work well as Map keys and Set elements • Are stable & fault tolerant • Can be shared freely • Work well as Map keys and Set elements Finally, Immutable objects are also a perfect option to use as Map keys and Set elements, since Map keys and Set elements must never change.
  • 68. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables work well as Map keys and Set elements These are the main advantages of Immutables. Let’s also look at their disadvantages.
  • 69. Copyright © 2016 Marcus Bielwww.marcus-biel.com Disadvantages of Immutables • May lead to performance problems The biggest disadvantage of Immutable classes is that their use may lead to performance problems. Let's see how.
  • 70. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables may lead to performance problems Object Immutables require a new object
  • 71. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables may lead to performance problems for every distinct state they represent.
  • 72. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables may lead to performance problems Therefore, the use of Immutables often increases the number of objects created.
  • 73. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables may lead to performance problems Naturally, the more objects that are created, the more system resources will be used.
  • 74. Copyright © 2016 Marcus Bielwww.marcus-biel.com Immutables may lead to performance problems However, this may not be a problem at all. There are many more influencing factors as we will see later on.
  • 75. Copyright © 2016 Marcus Bielwww.marcus-biel.com How to create an Immutable • What is an Immutable? • Advantages & disadvantages •How to create an Immutable • When to use Immutables So now that I’ve shown the value of an Immutable class. How can we actually make one?
  • 76. Copyright © 2016 Marcus Bielwww.marcus-biel.com How to create an Immutable • What is an Immutable? • Advantages & disadvantages •How to create an Immutable • When to use Immutables To make a class immutable, we have to follow a few rules:
  • 77. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final 1. Make all attributes private final. First of all, we have to make all its attributes private and final
  • 78. Copyright © 2016 Marcus Bielwww.marcus-biel.com private final String name; private final Destination destination; 1. Make all attributes private final public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } Let’s illustrate this by looking at the ImmutableSpaceship class I introduced you to before.
  • 79. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final private final String name; private final Destination destination; public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } We make the attributes private, so that no reference can be accessed from outside.
  • 80. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final private final String name; private final Destination destination; public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } While private variables cannot be accessed from outside the class, they can still be reassigned.
  • 81. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final private final String name; private final Destination destination; public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } To prevent this we also have to make all variables final.
  • 82. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final private final String name; private final Destination destination; public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } Setting all internal reference variables to final – clearly communicates our intent to make an immutable class.
  • 83. Copyright © 2016 Marcus Bielwww.marcus-biel.com 1. Make all attributes private final private final String name; private final Destination destination; public final class ImmutableSpaceship { public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } Should someone try to reassign a reference variable, a compiler error will occur.
  • 84. Copyright © 2016 Marcus Bielwww.marcus-biel.com 2. Don’t provide any methods that modify the object’s state 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. Okay. Second, we must not provide any methods that modify the object’s state.
  • 85. Copyright © 2016 Marcus Bielwww.marcus-biel.com 2. Don’t provide any methods that modify the object’s state 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. This I have already briefly discussed at the beginning of this presentation, but now we will look at it more closely.
  • 86. Copyright © 2016 Marcus Bielwww.marcus-biel.com public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } 2. Don’t provide any methods that modify the object’s state public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } For any change that you want to apply to your Immutable object, you have to provide a method that returns a new object.
  • 87. Copyright © 2016 Marcus Bielwww.marcus-biel.com 2. Don’t provide any methods that modify the object’s state public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } Attributes that do not change, like “name” in this case, can be copied from our current object.
  • 88. Copyright © 2016 Marcus Bielwww.marcus-biel.com 2. Don’t provide any methods that modify the object’s state public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } Attributes that do change, like “destination” in this case, have to be initialized with a new value instead.
  • 89. Copyright © 2016 Marcus Bielwww.marcus-biel.com 3. Ensure that the class can’t be extended 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. 3. Ensure that the class can’t be extended. Let’s go on to the next rule. To further protect our class from being changed, we also have to prevent it from being extended.
  • 90. Copyright © 2016 Marcus Bielwww.marcus-biel.com 3. Ensure that the class can’t be extended 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. 3. Ensure that the class can’t be extended. Extending a class would allow you to override its methods. This would allow you to directly change the “unchangeable" object.
  • 91. Copyright © 2016 Marcus Bielwww.marcus-biel.com 3. Ensure that the class can’t be extended 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. 3. Ensure that the class can’t be extended. Let's look at a code example to better illustrate this:
  • 92. Copyright © 2016 Marcus Bielwww.marcus-biel.com public class RomulanSpaceship extends ImmutableSpaceship { @Override public RomulanSpaceship exploreGalaxy() { this.destination = Destination.OUTER_SPACE; return this; } 3. Ensure that the class can’t be extended […] } private String name; private Destination destination; public RomulanSpaceship(String name) { super(name); } So here we have a RomulanSpaceship extending our ImmutableSpaceship.
  • 93. Copyright © 2016 Marcus Bielwww.marcus-biel.com @Override public RomulanSpaceship exploreGalaxy() { this.destination = Destination.NEUTRAL_ZONE; return this; } public class RomulanSpaceship extends ImmutableSpaceship { 3. Ensure that the class can’t be extended […] } private String name; private Destination destination; public RomulanSpaceship(String name) { super(name); } Its overridden exploreGalaxy() method violates the rules of an Immutable, as it directly changes the destination attribute.
  • 94. Copyright © 2016 Marcus Bielwww.marcus-biel.com ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen"); 3. Ensure that the class can’t be extended As RomulanSpaceship extends ImmutableSpaceship
  • 95. Copyright © 2016 Marcus Bielwww.marcus-biel.com 3. Ensure that the class can’t be extended ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen"); we can create an instance of a RomulanSpaceship,
  • 96. Copyright © 2016 Marcus Bielwww.marcus-biel.com 3. Ensure that the class can’t be extended ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen"); and assign it to an ImmutableSpaceship reference variable.
  • 97. Copyright © 2016 Marcus Bielwww.marcus-biel.com ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen"); […] immutableSpaceship.exploreGalaxy(); // internally changes the "immutable" Spaceship 3. Ensure that the class can’t be extended Much later in the code, in a different class and method, we will call the exploreGalaxy() method on our ImmutableSpaceship instance -
  • 98. Copyright © 2016 Marcus Bielwww.marcus-biel.com ImmutableSpaceship immutableSpaceship = new RomulanSpaceship("Battlequeen"); […] immutableSpaceship.exploreGalaxy(); // internally changes the "immutable" Spaceship 3. Ensure that the class can’t be extended which, much to our concern, will internally change the spaceship instance, which we expected to be unchangeable.
  • 99. Copyright © 2016 Marcus Bielwww.marcus-biel.com public final class ImmutableSpaceship { 3. Ensure that the class can’t be extended private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } public ImmutableSpaceship exploreGalaxy() { return new ImmutableSpaceship(name, Destination.OUTER_SPACE); } […] } To prevent this, we just have to make our class final. A final class can’t be extended, so it won’t be possible to override any method either.
  • 100. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes 1. Make all attributes private and final. 2. Don’t provide any methods that modify the object’s state. 3. Ensure that the class can’t be extended. 4. Ensure exclusive access to any mutable attributes. And now to the final rule – we have ensure exclusive access to any mutable attributes.
  • 101. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Here you can see a representation of our spaceship object. Name Spaceship DestinationName Immutable
  • 102. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes The attribute “name” is of type String, which is an Immutable. Name Spaceship DestinationName Immutable
  • 103. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes As I've already shown you, you can freely share Immutable attributes - Name Spaceship DestinationName Immutable
  • 104. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Name Spaceship DestinationName Immutable Mutable with other objects, as they cannot be changed.
  • 105. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable The Destination object, in this case, we’ll assume, is Mutable.
  • 106. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable Mutable Anyone who holds a reference to it -
  • 107. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable Mutable can alter it.
  • 108. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Immutable Mutable This will effectively alter our "Immutable" object.
  • 109. Copyright © 2016 Marcus Bielwww.marcus-biel.com Mutable 4. Ensure exclusive access to any mutable attributes In other words, it would not be immutable.
  • 110. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Mutable So to protect our Immutable object -
  • 111. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Mutable Spaceship DestinationName Immutable we have to isolate the mutable destination attribute from the outside and prevent anyone from getting hold of it.
  • 112. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable Destination Mutable To achieve this, we never obtain or return a direct reference to a destination object. Instead we create a deep copy and work with that instead.
  • 113. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable DestinationDestination Mutable As long as the mutable destination object is never directly shared,
  • 114. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable DestinationDestination Mutable a change inside an external object will not have any effect on our immutable object.
  • 115. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes Spaceship DestinationName Immutable DestinationDestination Mutable Okay, talk is cheap, show me the code.
  • 116. Copyright © 2016 Marcus Bielwww.marcus-biel.com public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } 4. Ensure exclusive access to any mutable attributes private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; To ensure exclusive access to our mutable destination attribute,
  • 117. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; we have to check all public methods and constructors for any incoming or outgoing Destination references.
  • 118. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; Let’s do this now.
  • 119. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; The public constructor does not receive any Destination reference.
  • 120. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; The Destination object it creates is safe, as it cannot be accessed from outside. So the public constructor is good as it is.
  • 121. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; The public currentDestination() method returns a reference -
  • 122. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; to our internal Destination object, so this must be fixed.
  • 123. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; Now, instead of returning the real reference we create a deep copy of our Destination object and return a reference to the copy instead.
  • 124. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; Finally, the public newDestination() method receives -
  • 125. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; a Destination reference -
  • 126. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; and forwards this reference to our private constructor.
  • 127. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; Now the private constructor directly stores the mutable Destination reference it receives.
  • 128. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; So, by following the execution path, we found that it is directly stored in the private constructor.
  • 129. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; This must not be allowed.
  • 130. Copyright © 2016 Marcus Bielwww.marcus-biel.com 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return new Destination(destination); } public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = new Destination(destination); } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; To stop it immediately, we store a reference to a deep copy of the external Destination object.
  • 131. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables • What is an Immutable? • Advantages & disadvantages • How to create an Immutable •When to use Immutables Okay. So I've shown you what an Immutable is, I've told you about its advantages and disadvantages, and finally, I have demonstrated how to create an Immutable class.
  • 132. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables There is just one last thing I would like to tell you – When should YOU actually use an Immutable class in your code?
  • 133. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables The question of whether you should design a specific class as an Immutable depends mainly on whether the performance of the overall system is sufficient or not.
  • 134. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables This again depends on the nature of the system and all aspects related to it. For example: What kind of specific problem are you trying to solve?
  • 135. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables On what kind of hardware is your program running? Is it a desktop or web application? It also depends on the internal structure of your code.
  • 136. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables For example: Of how many packages, classes and methods does your code consist of? As you can see, there is no simple answer to this very complex question.
  • 137. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables Each case must be looked at individually. As a general recommendation however, I advise you to follow this approach: Focus on designing a system that uses immutables to the greatest possible extent.
  • 138. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables Facilitate their use by designing simple classes with few attributes and methods. Immutables may become a burden when they are too complex. Simplicity is key.
  • 139. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables In this endeavor, Clean Code and Immutables are a well matched pair, reinforcing each other.
  • 140. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables In the majority of cases, this approach will lead to a system that exceeds all requirements.
  • 141. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables If however, testing reveals that you have not achieved satisfactory performance, relax the immutability rules gradually.
  • 142. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables As much as necessary, but as little as possible.
  • 143. Copyright © 2016 Marcus Bielwww.marcus-biel.com When to use Immutables Copyright © 2016 Marcus Biel All rights reserved.