SlideShare a Scribd company logo
1 of 32
Download to read offline
Make Your Life Better With
Immutable Objects
Maxim Novak, Wix
https://github.com/maximn@maximnovakmaximn@wix.com
I’m Maxim Novak
▪ Avid Scala advocate
▪ Team leader at Wix
▪ Building core services
▪ 10 years developing software
▪ TDD and clean code enthusiast
Lithuania
Vilnius
Kyiv
Dnipro
Wix Engineering Locations
Israel
Tel-Aviv
Be’er Sheva
Ukraine
What’s an immutable class?
An object is considered immutable if its state
cannot change after it is constructed.
Maximum reliance on immutable objects is
widely accepted as a sound strategy for
creating simple, reliable code.
...
- Oracle Java documentation
https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
GOOD QUESTION
But they made the most important one
immutable
java.lang.String
So why are most Java classes mutable?
What do you mean can’t change it ?!
So how do I work with it?
Create a new instance with the modified state
Person
Name
Birth
Date
Address
Huge data
Person moved =
person.moveTo(newAddress);
Something
Something
Something
Person’
Person
Name
Birth
Date
Address
Huge data
Address’
Something
Something
Something
Advantages
(Why do you want it)
You get a much simpler
programming model
“I think that large objected-oriented programs struggle with increasing complexity
as you build this large object graph of mutable objects. You know, trying to
understand and keep in your mind what will happen when you call a method and
what will the side effects be.”
- Rich Hickey (2010)
Easier to reason about
https://pixabay.com/en/fly-swatter-flyswatter-fly-flap-bug-149265/
void foo(SomeInterface func) {
Data data = new Data("initial state");
func.apply(data);
log(data);
}
Easier to reason about
Side-effect free (share safely)
https://pixabay.com/en/fly-swatter-flyswatter-fly-flap-bug-149265/
https://pixabay.com/en/chemistry-science-antique-bottles-3188870/
Easier to test
Easier to debug
https://pixabay.com/en/ladybugs-ladybirds-bugs-insects-1593406/
Avoid temporal coupling
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
req.bodyForm(
new BasicNameValuePair("action", "add-item"));
req.execute();
}
AddItem
CreateCart
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
req.bodyForm(
new BasicNameValuePair("action", "add-item"));
req.execute();
}
AddItem
CreateCart
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
req.bodyForm(
new BasicNameValuePair("action", "add-item"));
req.execute();
}
AddItem
CreateCart
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
req.bodyForm(
new BasicNameValuePair("action", "add-item"));
req.execute();
}
AddItem
CreateCart
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
addItem(req);
}
private void addItem(Request req) throws IOException {
req.bodyForm(
new BasicNameValuePair("action", "add-item"));
req.execute();
}
CreateCart
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
createCart(req);
addItem(req);
}
private void createCart(Request req) throws IOException {
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
}
void addItemToCart() throws IOException {
Request req = Request.Post("http://example.com");
createCart(req);
addItem(req);
}
private void createCart(Request req) throws IOException {
req.setHeader("Authorization", "token");
req.bodyForm(
new BasicNameValuePair("action", "create-cart"));
req.execute();
}
https://pixabay.com/en/fingerprint-brush-identity-search-2108872/
Avoiding Identity Mutability
Set<Date> set = new HashSet<>();
Date date = new Date(2);
set.add(date);
date.setTime(4);
System.out.println(set.contains(date));
HashCode Object
1
2
3
4
...
...
n
date(2)
date
Avoiding Identity Mutability
https://pixabay.com/en/hexanol-model-molecule-carbon-3d-835644/
Always have failure atomicity
Prevent NULL references
public class Person {
private String firstName;
private String lastName;
public Person() {
}
public void setName(String firstName, String lastName) {
throwOnInvalid(firstName);
this.firstName = firstName;
throwOnInvalid(lastName);
this.lastName = lastName;
}
...
BOOM!!!
http://www.freestockphotos.biz/stockphoto/17639
Always Thread safe
Advantages
(Why do you want it)
● Easier to reason about
● Side-effect free (share safely, no defensive copies)
● Easier to test
● Easier to debug
● Avoid temporal coupling
● Avoiding Identity Mutability
● Always have failure atomicity / Prevent NULL references
● Always Thread safe
Disadvantages
(What you should beware of )
● Performance under certain conditions.
● Brings some difficulties when working in Java
So how do I start?
(some rules of thumb)
● Make all fields final & private
● Create methods that create a copy
of the class with a modified state
● Disallow inheritance (final class)
So how do I start?
(some rules of thumb)
● If you’re using mutable classes inside
○ Copy them on construction
○ Don’t expose references to internal fields
(copy defensively)
○ Don’t provide any method that changes
the state (setters)
So how do I start?
(How can I make it easier?)
https://immutables.github.io/
Lombok, AutoValue, and Immutables
Project sample?
https://github.com/yegor256/takes
- Yegor Bugayenko (http://www.yegor256.com/)
1. not a single null (why NULL is bad?)
2. not a single public static method (why they are bad?)
3. not a single mutable class (why they are bad?)
4. not a single instanceof keyword, type casting, or reflection (why?)
‫״‬Simplicity is hard work. But, there's a huge payoff. The person
who has a genuinely simpler system - a system made out of
genuinely simple parts, is going to be able to affect the greatest
change with the least work. He's going to kick your ass. He's
gonna spend more time simplifying things up front and in the long
haul he's gonna wipe the plate with you because he'll have that
ability to change things when you're struggling to push elephants
around.‫״‬
— Rich Hickey, Creator of the Clojure programming language
Make Your Life Better With
Immutable Objects
Maxim Novak, Wix
https://github.com/maximn@maximnovakmaximn@wix.com

More Related Content

Similar to Make your life better with immutable objects

Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Doris Chen
 
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Roy de Kleijn
 
Stack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersStack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersJonathan Sharp
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web FrameworkLuther Baker
 
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIBrian Hogg
 
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.WO Community
 
Angular from a Different Angle
Angular from a Different AngleAngular from a Different Angle
Angular from a Different AngleJeremy Likness
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipseanshunjain
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedGil Fink
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - GreachHamletDRC
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsMike Subelsky
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaWO Community
 
JS FAST Prototyping with AngularJS & RequireJS
JS FAST Prototyping with AngularJS & RequireJSJS FAST Prototyping with AngularJS & RequireJS
JS FAST Prototyping with AngularJS & RequireJSYuriy Silvestrov
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012Nicholas Zakas
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page ObjectRevolution or Evolution in Page Object
Revolution or Evolution in Page ObjectArtem Sokovets
 
Web Components v1
Web Components v1Web Components v1
Web Components v1Mike Wilcox
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETBen Hall
 
Selenium interview questions and answers
Selenium interview questions and answersSelenium interview questions and answers
Selenium interview questions and answerskavinilavuG
 

Similar to Make your life better with immutable objects (20)

Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!Angular or Backbone: Go Mobile!
Angular or Backbone: Go Mobile!
 
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016Improving Your Selenium WebDriver Tests - Belgium testing days_2016
Improving Your Selenium WebDriver Tests - Belgium testing days_2016
 
Stack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for DevelopersStack Overflow Austin - jQuery for Developers
Stack Overflow Austin - jQuery for Developers
 
Introduction to React
Introduction to ReactIntroduction to React
Introduction to React
 
Apache Wicket Web Framework
Apache Wicket Web FrameworkApache Wicket Web Framework
Apache Wicket Web Framework
 
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST APIWordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
WordCamp Ann Arbor 2015 Introduction to Backbone + WP REST API
 
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
Beyond Fluffy Bunny. How I leveraged WebObjects in my lean startup.
 
Angular from a Different Angle
Angular from a Different AngleAngular from a Different Angle
Angular from a Different Angle
 
Understanding Framework Architecture using Eclipse
Understanding Framework Architecture using EclipseUnderstanding Framework Architecture using Eclipse
Understanding Framework Architecture using Eclipse
 
Stencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrivedStencil the time for vanilla web components has arrived
Stencil the time for vanilla web components has arrived
 
New Ideas for Old Code - Greach
New Ideas for Old Code - GreachNew Ideas for Old Code - Greach
New Ideas for Old Code - Greach
 
SproutCore and the Future of Web Apps
SproutCore and the Future of Web AppsSproutCore and the Future of Web Apps
SproutCore and the Future of Web Apps
 
Design patterns
Design patternsDesign patterns
Design patterns
 
Building Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with ScalaBuilding Concurrent WebObjects applications with Scala
Building Concurrent WebObjects applications with Scala
 
JS FAST Prototyping with AngularJS & RequireJS
JS FAST Prototyping with AngularJS & RequireJSJS FAST Prototyping with AngularJS & RequireJS
JS FAST Prototyping with AngularJS & RequireJS
 
Maintainable JavaScript 2012
Maintainable JavaScript 2012Maintainable JavaScript 2012
Maintainable JavaScript 2012
 
Revolution or Evolution in Page Object
Revolution or Evolution in Page ObjectRevolution or Evolution in Page Object
Revolution or Evolution in Page Object
 
Web Components v1
Web Components v1Web Components v1
Web Components v1
 
Testing ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NETTesting ASP.NET - Progressive.NET
Testing ASP.NET - Progressive.NET
 
Selenium interview questions and answers
Selenium interview questions and answersSelenium interview questions and answers
Selenium interview questions and answers
 

Recently uploaded

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptkotipi9215
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxTier1 app
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackVICTOR MAESTRE RAMIREZ
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxnada99848
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 

Recently uploaded (20)

EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
chapter--4-software-project-planning.ppt
chapter--4-software-project-planning.pptchapter--4-software-project-planning.ppt
chapter--4-software-project-planning.ppt
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptxKnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
KnowAPIs-UnknownPerf-jaxMainz-2024 (1).pptx
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
Cloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStackCloud Management Software Platforms: OpenStack
Cloud Management Software Platforms: OpenStack
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
software engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptxsoftware engineering Chapter 5 System modeling.pptx
software engineering Chapter 5 System modeling.pptx
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 

Make your life better with immutable objects

  • 1. Make Your Life Better With Immutable Objects Maxim Novak, Wix https://github.com/maximn@maximnovakmaximn@wix.com
  • 2. I’m Maxim Novak ▪ Avid Scala advocate ▪ Team leader at Wix ▪ Building core services ▪ 10 years developing software ▪ TDD and clean code enthusiast Lithuania Vilnius Kyiv Dnipro Wix Engineering Locations Israel Tel-Aviv Be’er Sheva Ukraine
  • 3. What’s an immutable class? An object is considered immutable if its state cannot change after it is constructed. Maximum reliance on immutable objects is widely accepted as a sound strategy for creating simple, reliable code. ... - Oracle Java documentation https://docs.oracle.com/javase/tutorial/essential/concurrency/immutable.html
  • 4. GOOD QUESTION But they made the most important one immutable java.lang.String So why are most Java classes mutable?
  • 5. What do you mean can’t change it ?! So how do I work with it? Create a new instance with the modified state
  • 6. Person Name Birth Date Address Huge data Person moved = person.moveTo(newAddress); Something Something Something
  • 8. Advantages (Why do you want it) You get a much simpler programming model
  • 9. “I think that large objected-oriented programs struggle with increasing complexity as you build this large object graph of mutable objects. You know, trying to understand and keep in your mind what will happen when you call a method and what will the side effects be.” - Rich Hickey (2010) Easier to reason about https://pixabay.com/en/fly-swatter-flyswatter-fly-flap-bug-149265/
  • 10. void foo(SomeInterface func) { Data data = new Data("initial state"); func.apply(data); log(data); } Easier to reason about Side-effect free (share safely)
  • 13. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); req.bodyForm( new BasicNameValuePair("action", "add-item")); req.execute(); } AddItem CreateCart
  • 14. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); req.bodyForm( new BasicNameValuePair("action", "add-item")); req.execute(); } AddItem CreateCart
  • 15. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); req.bodyForm( new BasicNameValuePair("action", "add-item")); req.execute(); } AddItem CreateCart
  • 16. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); req.bodyForm( new BasicNameValuePair("action", "add-item")); req.execute(); } AddItem CreateCart
  • 17. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); addItem(req); } private void addItem(Request req) throws IOException { req.bodyForm( new BasicNameValuePair("action", "add-item")); req.execute(); } CreateCart
  • 18. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); createCart(req); addItem(req); } private void createCart(Request req) throws IOException { req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); }
  • 19. void addItemToCart() throws IOException { Request req = Request.Post("http://example.com"); createCart(req); addItem(req); } private void createCart(Request req) throws IOException { req.setHeader("Authorization", "token"); req.bodyForm( new BasicNameValuePair("action", "create-cart")); req.execute(); }
  • 21. Set<Date> set = new HashSet<>(); Date date = new Date(2); set.add(date); date.setTime(4); System.out.println(set.contains(date)); HashCode Object 1 2 3 4 ... ... n date(2) date Avoiding Identity Mutability
  • 23. public class Person { private String firstName; private String lastName; public Person() { } public void setName(String firstName, String lastName) { throwOnInvalid(firstName); this.firstName = firstName; throwOnInvalid(lastName); this.lastName = lastName; } ... BOOM!!!
  • 25. Advantages (Why do you want it) ● Easier to reason about ● Side-effect free (share safely, no defensive copies) ● Easier to test ● Easier to debug ● Avoid temporal coupling ● Avoiding Identity Mutability ● Always have failure atomicity / Prevent NULL references ● Always Thread safe
  • 26. Disadvantages (What you should beware of ) ● Performance under certain conditions. ● Brings some difficulties when working in Java
  • 27. So how do I start? (some rules of thumb) ● Make all fields final & private ● Create methods that create a copy of the class with a modified state ● Disallow inheritance (final class)
  • 28. So how do I start? (some rules of thumb) ● If you’re using mutable classes inside ○ Copy them on construction ○ Don’t expose references to internal fields (copy defensively) ○ Don’t provide any method that changes the state (setters)
  • 29. So how do I start? (How can I make it easier?) https://immutables.github.io/ Lombok, AutoValue, and Immutables
  • 30. Project sample? https://github.com/yegor256/takes - Yegor Bugayenko (http://www.yegor256.com/) 1. not a single null (why NULL is bad?) 2. not a single public static method (why they are bad?) 3. not a single mutable class (why they are bad?) 4. not a single instanceof keyword, type casting, or reflection (why?)
  • 31. ‫״‬Simplicity is hard work. But, there's a huge payoff. The person who has a genuinely simpler system - a system made out of genuinely simple parts, is going to be able to affect the greatest change with the least work. He's going to kick your ass. He's gonna spend more time simplifying things up front and in the long haul he's gonna wipe the plate with you because he'll have that ability to change things when you're struggling to push elephants around.‫״‬ — Rich Hickey, Creator of the Clojure programming language
  • 32. Make Your Life Better With Immutable Objects Maxim Novak, Wix https://github.com/maximn@maximnovakmaximn@wix.com