Upgrade to Pro — share decks privately, control downloads, hide ads and more …

In a Nutshell: Immutable Classes

Marcus Biel
October 30, 2017

In a Nutshell: Immutable Classes

In this valuable talk, Marcus will describe exactly what immutable classes are. He'll tell you about their advantages and disadvantages, and show you how to create them. He'll finish by giving you concrete advice on when to use immutable classes in your daily work.

Marcus Biel

October 30, 2017
Tweet

More Decks by Marcus Biel

Other Decks in Education

Transcript

  1. Copyright © 2017 Marcus Biel www.cleancodeacademy.com About me @MarcusBiel
 Clean

    Code Evangelist JCP Member
 Senior Software Engineer
  2. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Outline • What is

    an Immutable Class? • Advantages of Immutable Classes • Disadvantages of Immutable Classes • How to create an Immutable Class?
  3. Copyright © 2017 Marcus Biel www.cleancodeacademy.com What is an Immutable

    Class? USS Enterprise (NCC-1701) ImmutableSpaceship enterprise = new ImmutableSpaceship("Enterprise");
 enterprise.exploreGalaxy();
  4. Copyright © 2017 Marcus Biel www.cleancodeacademy.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 Class?
  5. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Outline • What is

    an Immutable Class? • Advantages of Immutable Classes • Disadvantages of Immutable Classes • How to create an Immutable Class?
  6. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Advantages of Immutable Classes

    • Are stable • Are fault tolerant (Failure Atomicity) • Can be shared freely • Work well as Map keys and Set elements
  7. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Immutable Objects are stable

    private void validate(long balance) { if (balance < 0) { throw new IllegalArgumentException("balance must not be negative:"+ balance); } }
  8. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 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) {…} […] } Immutable Objects are stable
  9. Copyright © 2017 Marcus Biel www.cleancodeacademy.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) {…} […] } Immutable Objects are stable
  10. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Advantages of Immutable Classes

    • Are stable • Are fault tolerant (Failure Atomicity) • Can be shared freely • Work well as Map keys and Set elements
  11. Copyright © 2017 Marcus Biel www.cleancodeacademy.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) { } […] } Immutable Objects are fault tolerant
  12. Copyright © 2017 Marcus Biel www.cleancodeacademy.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) { // error during balance calculation } […] } Immutable Objects are fault tolerant
  13. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Advantages of Immutable Classes

    • Are stable • Are fault tolerant (Failure Atomicity) • Can be shared freely • Work well as Map keys and Set elements
  14. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Immutable Objects can be

    shared freely Balance Account Account Holder Holder Balance
  15. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Immutable Objects can be

    shared freely Account Account Holder Holder Balance
  16. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Immutable Objects can be

    shared freely Account Balance Holder Account Holder Balance
  17. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Advantages of Immutable Classes

    • Are stable • Are fault tolerant (Failure Atomicity) • Can be shared freely • Work well as Map keys and Set elements
  18. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Outline • What is

    an Immutable Class? • Advantages of Immutable Classes • Disadvantages of Immutable Classes • How to create an Immutable Class?
  19. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Outline • What is

    an Immutable Class? • Advantages of Immutable Classes • Disadvantages of Immutable Classes • How to create an Immutable Class?
  20. Copyright © 2017 Marcus Biel www.cleancodeacademy.com How to create an

    Immutable Class 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. How to create an Immutable Class
  21. Copyright © 2017 Marcus Biel www.cleancodeacademy.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); } […] }
  22. Copyright © 2017 Marcus Biel www.cleancodeacademy.com How to create an

    Immutable Class 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.
  23. Copyright © 2017 Marcus Biel www.cleancodeacademy.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; } […] }
  24. Copyright © 2017 Marcus Biel www.cleancodeacademy.com How to create an

    Immutable Class 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.
  25. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public class RomulanSpaceship extends

    ImmutableSpaceship { 3. Ensure that the class can’t be extended […] } public RomulanSpaceship(String name) { super(name); }
  26. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public class RomulanSpaceship extends

    ImmutableSpaceship { 3. Ensure that the class can’t be extended […] } public RomulanSpaceship(String name) { super(name); } private String evilName; private Destination evilDestination;
  27. Copyright © 2017 Marcus Biel www.cleancodeacademy.com private String evilName; private

    Destination evilDestination; public class RomulanSpaceship extends ImmutableSpaceship { 3. Ensure that the class can’t be extended […] } public RomulanSpaceship(String name) { super(name); } @Override public ImmutableSpaceship newDestination(Destination newDestination) { this.evilDestination = newDestination; return this; }
  28. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 3. Ensure that the

    class can’t be extended public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = Destination.NONE; }
  29. Copyright © 2017 Marcus Biel www.cleancodeacademy.com How to create an

    Immutable Class 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.
  30. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable
  31. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable
  32. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Name Spaceship Destination Name Immutable Mutable
  33. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable
  34. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable Mutable
  35. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable Mutable
  36. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Mutable Spaceship Destination Name Immutable
  37. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable Destination Mutable
  38. Copyright © 2017 Marcus Biel www.cleancodeacademy.com 4. Ensure exclusive access

    to any mutable attributes Spaceship Destination Name Immutable Destination Destination Mutable
  39. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public ImmutableSpaceship(String name) {

    this.name = name; this.destination = new Destination("NONE"); } 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } public Destination currentDestination() { return destination; } private ImmutableSpaceship(String name, Destination destination) { this.name = name; this.destination = destination; } […] } public final class ImmutableSpaceship { private final String name; private final Destination destination;
  40. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public Destination currentDestination() {

    return destination; } 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } 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;
  41. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public Destination currentDestination() {

    return destination; } 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } 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;
  42. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public Destination currentDestination() {

    return new Destination(destination); } 4. Ensure exclusive access to any mutable attributes public ImmutableSpaceship newDestination(Destination newDestination) { return new ImmutableSpaceship(this.name, newDestination); } 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;
  43. Copyright © 2017 Marcus Biel www.cleancodeacademy.com public ImmutableSpaceship newDestination(Destination newDestination)

    { return new ImmutableSpaceship(this.name, newDestination); } 4. Ensure exclusive access to any mutable attributes 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;
  44. Copyright © 2017 Marcus Biel www.cleancodeacademy.com private ImmutableSpaceship(String name, Destination

    destination) { this.name = name; this.destination = destination; } 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 final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); }
  45. Copyright © 2017 Marcus Biel www.cleancodeacademy.com private ImmutableSpaceship(String name, Destination

    destination) { this.name = name; this.destination = new Destination(destination); } 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 final class ImmutableSpaceship { private final String name; private final Destination destination; public ImmutableSpaceship(String name) { this.name = name; this.destination = new Destination("NONE"); }
  46. Copyright © 2017 Marcus Biel www.cleancodeacademy.com Conclusion Immutable Classes… •

    Enforce Encapsulation • Enforce Simplicity • Enforce Clean Architecture