SlideShare a Scribd company logo
victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro
The Hitchhiker Guider to
Victor Rentea
Best Talks:
VictorRentea.ro
Independent Trainer & Consultant
Founder of
Bucharest Software Craftsmanship Community
Java Champion
❤️ Simple Design, Refactoring, Unit Testing ❤️
Technical Training
HibernateSpring Func Prog in Java
300+ days2000 devs8 years
Details for you or your company: VictorRentea.ro
40 companies
Follow me:
35K 4K 3K
Java PerformanceReactive-X
Design Patterns
Clean Code
Refactoring
Unit Testing
TDD
any
lang
162 © VictorRentea.ro
a training by
Life
163 © VictorRentea.ro
a training by
checkCustomer(customer);
checkOrder(customer, order);
Mock-full tests
Race Bugs
A method changes a parameter: Surprise!
Different Results for Same Inputs
customer.setActive(true);
Temporal Coupling
164 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return resultssearch(criteria):List
computePrice(movie):int
in 1994, by Bertrand Meyer
Pure Functions
165 © VictorRentea.ro
a training by
No side effects
No INSERTs, POSTs, queues, files, fields,…
= 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2
+ 𝑦
(logging doesn't count)
Referential Transparent
Same arguments ➔ same result
No current time, random, GET, SELECT…
≠ Idempotent
Pure Functions
167 © VictorRentea.ro
a training by
Pure Functions : Quiz
f1(int x) {return x + 1;}
f2(Data d) {return ++d.x;}
f3() {d.incrementX(); return d.x;}
f4() {return querySQL(...);}
f5(int y) { return this.x + y; }
f6(Data d, int y) { return d.getX() + y; }
f7(int i) { if (i<0) throw new WrongInputException(); }
is this immutable?
Probable side effects
Expected to be pure
168 © VictorRentea.ro
a training by
throw new E(); is pure
f(x) {
try {
//
}
}
catch (E) is pure?
if it always throws for the same inputs
it depends ...
* Some slightly disagree
on E
NO, if E can happen randomly
eg. IOException, OutOfMemory
YES, if E is thrown deterministically*
➔ Catch unexpected exceptions
in the outskirts of your code
169 © VictorRentea.ro
a training by
Why we Love Pure Functions
➢No hidden inputs, only plain-sight return values and parameters
➢Easier to understand
➢Testable (less setup)
➢Fast & Composable: free to call them n times
➢No temporal coupling
➢Parallelizable
170 © VictorRentea.ro
a training by
That's it!
I'll only write pure functions from now!
impossible
What kind of app doesn't change anything?
172 © VictorRentea.ro
a training by
In Java there's no way to strictly enforce purity
So we'll live with both pure and impure functions
But how do we distinguish them?
173 © VictorRentea.ro
a training by
do side-effects
return void sendEmail(Email):void
Command-Query Separation
setActive(true):void
return results
pure functions
search():List
computePrice(movie):int
Highlight Side Effects
computePriceAndAdjustMetrics(movie):int
174 © VictorRentea.ro
a training by
You can do better!
178 © VictorRentea.ro
a training by
179 © VictorRentea.ro
a training by
functional core
Side-effects (Writes) +
Non-deterministic Reads
Expose them
Purify the most complex parts of your logic!
180 © VictorRentea.ro
a training by
Purify the most complex parts of your logic!
182 © VictorRentea.ro
a training by
Purifying Logic
Time and Random
Amount of time-dependent logic:
➢None (e.setCreationDate(now());) ➔ tolerate
➢Very little ➔ Inject a Clock / TimeProvider
➢Heavy (x-rare) ➔ expose a ..., time); parameter
183 © VictorRentea.ro
a training by
Purifying Logic
No Files in Functional Core
185 © VictorRentea.ro
a training by
Purifying Logic
Expose Read/Write from DB/APIs
Initial Read
Intermediary
(conditional?)
➔ Pass as Parameters
➔ Split-Phase Refactor f();
r=read();
f(r);
Writing Results ➔ Return Changes w=f();
persist(w);
r=read()
186 © VictorRentea.ro
a training by
Purifying Logic
Expose Read/Write from DB/APIs
Initial Read
Intermediary
(conditional?)
➔ Pass as Parameters
➔ Split-Phase Refactor
r=read();
f(r);
r1=f1()
f2(r,r1...)
expose impurity
Writing Results ➔ Return Changes w=f();
persist(w);
r=read()
187 © VictorRentea.ro
a training by
Implement as much logic
as pure functions
exposing impurity to the surface
188 © VictorRentea.ro
a training by
Purifying Logic
Changing Objects' State
Immutable Objects
190 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void h() {
Data data = new Data(1);
obj.setData(data);
g(data);
}
obj
void g(Data data) {
data.setX(2);
mutateParam(data);
obj.mutateField();
f(data);
}
void setData(Data data) {
this.data = data;
}
void mutateField() {
this.data.setX(2);
}
same obj
in h() and g()
void mutateParam(Data data) {
data.setX(1);
}
x=
Long-lived mutable data
A Code Inspection Session
What code ran before,
having a reference
to my data instance?!
Mutable Data
191 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void h() {
Data data = new Data(1);
obj.setData(data);
g(data);
}
obj
void g(Data data) {
data.setX(2);
mutateParam(data);
obj.mutateField();
f(data);
}
void setData(Data data) {
this.data = data;
}
void mutateField() {
this.data.setX(2);
}
same obj
in h() and g()
void mutateParam(Data data) {
data.setX(1);
}
x=
Long-lived mutable data
A Code Inspection Session
What code ran before,
having a reference
to my data instance?!
Mutable DataImmutable Data
192 © VictorRentea.ro
a training by
void f(Data data) {
...
if (data.getX() == 1) {
// will this run ?
}
}
void g(Data data) {
f(data);
}
void h() {
Data data = new Data(1);
g(data);
}
A Code Inspection Session
Immutable Data
Who created
the instance?!
Easier to trace
data changes
Real-world: 4+ functions in between
...
Real-world: 4+
...
x=
193 © VictorRentea.ro
a training by
Designing Immutable Classes
public class A {
private final String s;
private final B b;
private final List<String> list;
public A(String s, B b, List<String> list) {
this.s = s;
this.b = b;
this.list = new ArrayList<>(list);
// validation ...
}
public List<String> getList() {
return unmodifiableList(list);
}
// other getters
// hashCode, equals on all fields = Value Object
// bits of LOGIC 💪
public A withS(String newS) {
return new A(newS, b, list);
}
}
Mutates by creating
a new instance
Stops creator keeping a reference
Overkill, as problem is not the creator but the "man-in-the-middle"
Oh, so
we CAN
mutate them!
@lombok.With
Iterable<String> getList() {
List<? extends String> getList() {or
record
(java 15)
Java collections are mutable😞
final
Afraid of hackers? 😨
@lombok.Value
or, until then...
194 © VictorRentea.ro
a training by
195 © VictorRentea.ro
a training by
A function changing the object has to return it:
data = f(data);
Imagine data has 20 fields
When did data.x change?
... every time
data = g(data);
data = h(data);
The mess is still here!
196 © VictorRentea.ro
a training by
data = f(data);
final variables won't allow this
IntelliJ underlines
reassigned variables ❤️
By the way, there are ways to add final automatically at code cleanup
Real Problem
Too Large Immutable Objects
smallerData = f(...);
➔ break them
If they change together,
they stick together
data = g(data);
data = h(data);
withX
withY
withZ
197 © VictorRentea.ro
a training by
Wait a second,
I know...
198 © VictorRentea.ro
a training by
void f(VO[] arr) {
arr[0] = arr[0].withX(-99);
}
void f(List<String> list) {
list.removeIf(String::isBlank);
}
void f(Map<Integer, VO> map) {
map.put(1, map.get(1).withX(-99));
}
map.get(1).withX(-99)
199 © VictorRentea.ro
a training by
Don't
ever
mutate
collections!
➔ Create new ones
200 © VictorRentea.ro
a training by
Why we Immutable objects
Easier to trace data changes
Can enforce validation in constructor
Safe to put in Set or Map(as keys)
Thread-safe ➔ no race bugs, since they can't be changed
201 © VictorRentea.ro
a training by
All right cowboy!
Only immutable objects from now on!
usually that's too much!
202 © VictorRentea.ro
a training by
Value Object vs Reference Object
class Customer {
id // PK in DB
name
phone
}
class Money {
amount
currency
}
equals(): using what fields ?
idamount, currency
final
final
Make VOs immutable!
Should Entities
be immutable?
No matter how different two instances are,
if they have the same id, it's the same Customer
203 © VictorRentea.ro
a training by
instead,
Extract immutable Value Objects from them
Leaving the root Entity mutable
NO*
*there are few cases when it pays to, but those apps typically don't persist their data
Should Entities be immutable?
204 © VictorRentea.ro
a training by
Entity
(mutable)
Persistent Leaf
eg. FullName
Immutable Objects in Real Life
Runtime Objects
(non-persistent data)
continuously
break XL entities
Hibernate: @Embeddable
206 © VictorRentea.ro
a training by
The Big Deal
207 © VictorRentea.ro
a training by
The Big Deal
Don't mutate objects on long workflows!
a(e) b(x) c(x) d(x) e(x) f(x) g(e) {
e.setField(...);
}
a(e) {
String s = b(vo);
e.setField(s);
}
b(…) c(…) d(…) e(…) f(…) g(…) {return ...;}
1) vavr.Tuple3<String,String,Integer>
2) NewConceptVO #kudos if you can find a good name!
can be pure functions
Immutable Arguments
Return the change to the surface, and apply it there
How to return changes
to multiple fields:
208 © VictorRentea.ro
a training by
The Big Deal
Is when immutable objects travel lots of code
209 © VictorRentea.ro
a training by
Performance of Immutability
210 © VictorRentea.ro
a training by
Performance of Immutability
Measure it !
(and you might have a surprise)
212 © VictorRentea.ro
a training by
Avoid Immutable Objects If
- Trashing millions of instances/second
- Cloning Lots of Lists
- Trivial logic
- Persistent Entities
213 © VictorRentea.ro
a training by
Take-Aways
➢ Complex logic ➔ pure functions using immutable objects
➢ Functional Core / Imperative Shell
➢ Pull impure remote/DB calls in the shell
➢ We'll change it in there ➔ compute and return
➢ Without proper mindset, immutability can hurt
➢ Don't mutate: argument state, variables or collections
➢ Immutable: runtime data or persistent leaves
➢ We'll change it in there ➔ compute and return
And no, I'm against OOP; but not in huge logic code ➔
214 © VictorRentea.ro
a training by
victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro
➢We'll change it in there ➔ compute and return

More Related Content

PDF
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
PDF
The Art of Unit Testing - Towards a Testable Design
PDF
Pure functions and immutable objects @dev nexus 2021
PDF
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
PDF
Don't Be Mocked by your Mocks - Best Practices using Mocks
PDF
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
PDF
Hibernate and Spring - Unleash the Magic
PDF
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
The Art of Unit Testing - Towards a Testable Design
Pure functions and immutable objects @dev nexus 2021
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Don't Be Mocked by your Mocks - Best Practices using Mocks
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Hibernate and Spring - Unleash the Magic
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021

What's hot (20)

PDF
Clean Lambdas & Streams in Java8
PDF
Integration testing with spring @snow one
PDF
Clean pragmatic architecture @ devflix
PDF
Refactoring Games - 15 things to do after Extract Method
PDF
Clean architecture - Protecting the Domain
PDF
The Proxy Fairy, and The Magic of Spring Framework
PDF
Integration testing with spring @JAX Mainz
PDF
Definitive Guide to Working With Exceptions in Java
PDF
Unit Testing like a Pro - The Circle of Purity
PPTX
Clean Code with Java 8 - Functional Patterns and Best Practices
PPTX
Clean Pragmatic Architecture - Avoiding a Monolith
PPTX
Functional Patterns with Java8 at Devoxx UK - Slides
PDF
Refactoring blockers and code smells @jNation 2021
PPTX
The Art of Clean code
PPTX
Clean Code
PPTX
Functional Patterns with Java8 @Bucharest Java User Group
PDF
關於測試,我說的其實是......
PDF
Living With Legacy Code
PPTX
Spring @Transactional Explained
PDF
Pharo Optimising JIT Internals
Clean Lambdas & Streams in Java8
Integration testing with spring @snow one
Clean pragmatic architecture @ devflix
Refactoring Games - 15 things to do after Extract Method
Clean architecture - Protecting the Domain
The Proxy Fairy, and The Magic of Spring Framework
Integration testing with spring @JAX Mainz
Definitive Guide to Working With Exceptions in Java
Unit Testing like a Pro - The Circle of Purity
Clean Code with Java 8 - Functional Patterns and Best Practices
Clean Pragmatic Architecture - Avoiding a Monolith
Functional Patterns with Java8 at Devoxx UK - Slides
Refactoring blockers and code smells @jNation 2021
The Art of Clean code
Clean Code
Functional Patterns with Java8 @Bucharest Java User Group
關於測試,我說的其實是......
Living With Legacy Code
Spring @Transactional Explained
Pharo Optimising JIT Internals
Ad

Similar to Pure Functions and Immutable Objects (20)

PDF
Transaction is a monad
PPTX
Programming picaresque
PDF
Functional Programming 101 for Java 7 Developers
PDF
Pragmatic functional refactoring with java 8
PDF
functional groovy
PDF
Intro to functional programming - Confoo
PDF
Pragmatic Functional Refactoring with Java 8
PDF
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
PDF
Pragmatic functional refactoring with java 8 (1)
PPTX
Immutable Classes in Java
PDF
Value Objects
PDF
What is Pure Functional Programming, and how it can improve our application t...
PDF
Functional Principles for OO Developers
PDF
If You Think You Can Stay Away from Functional Programming, You Are Wrong
PPTX
Functional programming principles and Java 8
KEY
Scala: functional programming for the imperative mind
PDF
Make your life better with immutable objects
PPTX
About Functional Programming
PDF
It's All About Morphisms
PDF
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Func...
Transaction is a monad
Programming picaresque
Functional Programming 101 for Java 7 Developers
Pragmatic functional refactoring with java 8
functional groovy
Intro to functional programming - Confoo
Pragmatic Functional Refactoring with Java 8
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Pragmatic functional refactoring with java 8 (1)
Immutable Classes in Java
Value Objects
What is Pure Functional Programming, and how it can improve our application t...
Functional Principles for OO Developers
If You Think You Can Stay Away from Functional Programming, You Are Wrong
Functional programming principles and Java 8
Scala: functional programming for the imperative mind
Make your life better with immutable objects
About Functional Programming
It's All About Morphisms
A Functional Approach to Java: Augmenting Object-Oriented Java Code with Func...
Ad

More from Victor Rentea (18)

PDF
Top REST API Desgin Pitfalls @ Devoxx 2024
PDF
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
PDF
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
PDF
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
PDF
Microservice Resilience Patterns @VoxxedCern'24
PDF
Distributed Consistency.pdf
PDF
Testing Microservices @DevoxxBE 23.pdf
PPTX
From Web to Flux @DevoxxBE 2023.pptx
PPTX
Test-Driven Design Insights@DevoxxBE 2023.pptx
PDF
Profiling your Java Application
PPTX
OAuth in the Wild
PPTX
The tests are trying to tell you something@VoxxedBucharest.pptx
PPTX
Vertical Slicing Architectures
PDF
Software Craftsmanship @Code Camp Festival 2022.pdf
PDF
Unit testing - 9 design hints
PPTX
Extreme Professionalism - Software Craftsmanship
PDF
TDD Mantra
PDF
Extreme Professionalism - Software Craftsmanship
Top REST API Desgin Pitfalls @ Devoxx 2024
The Joy of Testing - Deep Dive @ Devoxx Belgium 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Microservice Resilience Patterns @VoxxedCern'24
Distributed Consistency.pdf
Testing Microservices @DevoxxBE 23.pdf
From Web to Flux @DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
Profiling your Java Application
OAuth in the Wild
The tests are trying to tell you something@VoxxedBucharest.pptx
Vertical Slicing Architectures
Software Craftsmanship @Code Camp Festival 2022.pdf
Unit testing - 9 design hints
Extreme Professionalism - Software Craftsmanship
TDD Mantra
Extreme Professionalism - Software Craftsmanship

Recently uploaded (20)

PPTX
Spectroscopy.pptx food analysis technology
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PDF
Agricultural_Statistics_at_a_Glance_2022_0.pdf
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
PPTX
20250228 LYD VKU AI Blended-Learning.pptx
PDF
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
PDF
Encapsulation_ Review paper, used for researhc scholars
PDF
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
PDF
Building Integrated photovoltaic BIPV_UPV.pdf
PPTX
Digital-Transformation-Roadmap-for-Companies.pptx
PDF
Machine learning based COVID-19 study performance prediction
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Encapsulation theory and applications.pdf
PDF
Electronic commerce courselecture one. Pdf
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Unlocking AI with Model Context Protocol (MCP)
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PPTX
Programs and apps: productivity, graphics, security and other tools
Spectroscopy.pptx food analysis technology
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Agricultural_Statistics_at_a_Glance_2022_0.pdf
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
Advanced methodologies resolving dimensionality complications for autism neur...
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
20250228 LYD VKU AI Blended-Learning.pptx
Blue Purple Modern Animated Computer Science Presentation.pdf.pdf
Encapsulation_ Review paper, used for researhc scholars
TokAI - TikTok AI Agent : The First AI Application That Analyzes 10,000+ Vira...
Building Integrated photovoltaic BIPV_UPV.pdf
Digital-Transformation-Roadmap-for-Companies.pptx
Machine learning based COVID-19 study performance prediction
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Encapsulation theory and applications.pdf
Electronic commerce courselecture one. Pdf
MYSQL Presentation for SQL database connectivity
Unlocking AI with Model Context Protocol (MCP)
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Programs and apps: productivity, graphics, security and other tools

Pure Functions and Immutable Objects

  • 1. victor.rentea@gmail.com ♦ ♦ @victorrentea ♦ VictorRentea.ro The Hitchhiker Guider to
  • 2. Victor Rentea Best Talks: VictorRentea.ro Independent Trainer & Consultant Founder of Bucharest Software Craftsmanship Community Java Champion ❤️ Simple Design, Refactoring, Unit Testing ❤️
  • 3. Technical Training HibernateSpring Func Prog in Java 300+ days2000 devs8 years Details for you or your company: VictorRentea.ro 40 companies Follow me: 35K 4K 3K Java PerformanceReactive-X Design Patterns Clean Code Refactoring Unit Testing TDD any lang
  • 4. 162 © VictorRentea.ro a training by Life
  • 5. 163 © VictorRentea.ro a training by checkCustomer(customer); checkOrder(customer, order); Mock-full tests Race Bugs A method changes a parameter: Surprise! Different Results for Same Inputs customer.setActive(true); Temporal Coupling
  • 6. 164 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return resultssearch(criteria):List computePrice(movie):int in 1994, by Bertrand Meyer Pure Functions
  • 7. 165 © VictorRentea.ro a training by No side effects No INSERTs, POSTs, queues, files, fields,… = 𝑀𝑎𝑡ℎ𝑒𝑚𝑎𝑡𝑖𝑐𝑎𝑙 𝐹𝑢𝑛𝑐𝑡𝑖𝑜𝑛𝑠: 𝑓 𝑥, 𝑦 = 𝑥2 + 𝑦 (logging doesn't count) Referential Transparent Same arguments ➔ same result No current time, random, GET, SELECT… ≠ Idempotent Pure Functions
  • 8. 167 © VictorRentea.ro a training by Pure Functions : Quiz f1(int x) {return x + 1;} f2(Data d) {return ++d.x;} f3() {d.incrementX(); return d.x;} f4() {return querySQL(...);} f5(int y) { return this.x + y; } f6(Data d, int y) { return d.getX() + y; } f7(int i) { if (i<0) throw new WrongInputException(); } is this immutable? Probable side effects Expected to be pure
  • 9. 168 © VictorRentea.ro a training by throw new E(); is pure f(x) { try { // } } catch (E) is pure? if it always throws for the same inputs it depends ... * Some slightly disagree on E NO, if E can happen randomly eg. IOException, OutOfMemory YES, if E is thrown deterministically* ➔ Catch unexpected exceptions in the outskirts of your code
  • 10. 169 © VictorRentea.ro a training by Why we Love Pure Functions ➢No hidden inputs, only plain-sight return values and parameters ➢Easier to understand ➢Testable (less setup) ➢Fast & Composable: free to call them n times ➢No temporal coupling ➢Parallelizable
  • 11. 170 © VictorRentea.ro a training by That's it! I'll only write pure functions from now! impossible What kind of app doesn't change anything?
  • 12. 172 © VictorRentea.ro a training by In Java there's no way to strictly enforce purity So we'll live with both pure and impure functions But how do we distinguish them?
  • 13. 173 © VictorRentea.ro a training by do side-effects return void sendEmail(Email):void Command-Query Separation setActive(true):void return results pure functions search():List computePrice(movie):int Highlight Side Effects computePriceAndAdjustMetrics(movie):int
  • 14. 174 © VictorRentea.ro a training by You can do better!
  • 16. 179 © VictorRentea.ro a training by functional core Side-effects (Writes) + Non-deterministic Reads Expose them Purify the most complex parts of your logic!
  • 17. 180 © VictorRentea.ro a training by Purify the most complex parts of your logic!
  • 18. 182 © VictorRentea.ro a training by Purifying Logic Time and Random Amount of time-dependent logic: ➢None (e.setCreationDate(now());) ➔ tolerate ➢Very little ➔ Inject a Clock / TimeProvider ➢Heavy (x-rare) ➔ expose a ..., time); parameter
  • 19. 183 © VictorRentea.ro a training by Purifying Logic No Files in Functional Core
  • 20. 185 © VictorRentea.ro a training by Purifying Logic Expose Read/Write from DB/APIs Initial Read Intermediary (conditional?) ➔ Pass as Parameters ➔ Split-Phase Refactor f(); r=read(); f(r); Writing Results ➔ Return Changes w=f(); persist(w); r=read()
  • 21. 186 © VictorRentea.ro a training by Purifying Logic Expose Read/Write from DB/APIs Initial Read Intermediary (conditional?) ➔ Pass as Parameters ➔ Split-Phase Refactor r=read(); f(r); r1=f1() f2(r,r1...) expose impurity Writing Results ➔ Return Changes w=f(); persist(w); r=read()
  • 22. 187 © VictorRentea.ro a training by Implement as much logic as pure functions exposing impurity to the surface
  • 23. 188 © VictorRentea.ro a training by Purifying Logic Changing Objects' State Immutable Objects
  • 24. 190 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void h() { Data data = new Data(1); obj.setData(data); g(data); } obj void g(Data data) { data.setX(2); mutateParam(data); obj.mutateField(); f(data); } void setData(Data data) { this.data = data; } void mutateField() { this.data.setX(2); } same obj in h() and g() void mutateParam(Data data) { data.setX(1); } x= Long-lived mutable data A Code Inspection Session What code ran before, having a reference to my data instance?! Mutable Data
  • 25. 191 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void h() { Data data = new Data(1); obj.setData(data); g(data); } obj void g(Data data) { data.setX(2); mutateParam(data); obj.mutateField(); f(data); } void setData(Data data) { this.data = data; } void mutateField() { this.data.setX(2); } same obj in h() and g() void mutateParam(Data data) { data.setX(1); } x= Long-lived mutable data A Code Inspection Session What code ran before, having a reference to my data instance?! Mutable DataImmutable Data
  • 26. 192 © VictorRentea.ro a training by void f(Data data) { ... if (data.getX() == 1) { // will this run ? } } void g(Data data) { f(data); } void h() { Data data = new Data(1); g(data); } A Code Inspection Session Immutable Data Who created the instance?! Easier to trace data changes Real-world: 4+ functions in between ... Real-world: 4+ ... x=
  • 27. 193 © VictorRentea.ro a training by Designing Immutable Classes public class A { private final String s; private final B b; private final List<String> list; public A(String s, B b, List<String> list) { this.s = s; this.b = b; this.list = new ArrayList<>(list); // validation ... } public List<String> getList() { return unmodifiableList(list); } // other getters // hashCode, equals on all fields = Value Object // bits of LOGIC 💪 public A withS(String newS) { return new A(newS, b, list); } } Mutates by creating a new instance Stops creator keeping a reference Overkill, as problem is not the creator but the "man-in-the-middle" Oh, so we CAN mutate them! @lombok.With Iterable<String> getList() { List<? extends String> getList() {or record (java 15) Java collections are mutable😞 final Afraid of hackers? 😨 @lombok.Value or, until then...
  • 29. 195 © VictorRentea.ro a training by A function changing the object has to return it: data = f(data); Imagine data has 20 fields When did data.x change? ... every time data = g(data); data = h(data); The mess is still here!
  • 30. 196 © VictorRentea.ro a training by data = f(data); final variables won't allow this IntelliJ underlines reassigned variables ❤️ By the way, there are ways to add final automatically at code cleanup Real Problem Too Large Immutable Objects smallerData = f(...); ➔ break them If they change together, they stick together data = g(data); data = h(data); withX withY withZ
  • 31. 197 © VictorRentea.ro a training by Wait a second, I know...
  • 32. 198 © VictorRentea.ro a training by void f(VO[] arr) { arr[0] = arr[0].withX(-99); } void f(List<String> list) { list.removeIf(String::isBlank); } void f(Map<Integer, VO> map) { map.put(1, map.get(1).withX(-99)); } map.get(1).withX(-99)
  • 33. 199 © VictorRentea.ro a training by Don't ever mutate collections! ➔ Create new ones
  • 34. 200 © VictorRentea.ro a training by Why we Immutable objects Easier to trace data changes Can enforce validation in constructor Safe to put in Set or Map(as keys) Thread-safe ➔ no race bugs, since they can't be changed
  • 35. 201 © VictorRentea.ro a training by All right cowboy! Only immutable objects from now on! usually that's too much!
  • 36. 202 © VictorRentea.ro a training by Value Object vs Reference Object class Customer { id // PK in DB name phone } class Money { amount currency } equals(): using what fields ? idamount, currency final final Make VOs immutable! Should Entities be immutable? No matter how different two instances are, if they have the same id, it's the same Customer
  • 37. 203 © VictorRentea.ro a training by instead, Extract immutable Value Objects from them Leaving the root Entity mutable NO* *there are few cases when it pays to, but those apps typically don't persist their data Should Entities be immutable?
  • 38. 204 © VictorRentea.ro a training by Entity (mutable) Persistent Leaf eg. FullName Immutable Objects in Real Life Runtime Objects (non-persistent data) continuously break XL entities Hibernate: @Embeddable
  • 39. 206 © VictorRentea.ro a training by The Big Deal
  • 40. 207 © VictorRentea.ro a training by The Big Deal Don't mutate objects on long workflows! a(e) b(x) c(x) d(x) e(x) f(x) g(e) { e.setField(...); } a(e) { String s = b(vo); e.setField(s); } b(…) c(…) d(…) e(…) f(…) g(…) {return ...;} 1) vavr.Tuple3<String,String,Integer> 2) NewConceptVO #kudos if you can find a good name! can be pure functions Immutable Arguments Return the change to the surface, and apply it there How to return changes to multiple fields:
  • 41. 208 © VictorRentea.ro a training by The Big Deal Is when immutable objects travel lots of code
  • 42. 209 © VictorRentea.ro a training by Performance of Immutability
  • 43. 210 © VictorRentea.ro a training by Performance of Immutability Measure it ! (and you might have a surprise)
  • 44. 212 © VictorRentea.ro a training by Avoid Immutable Objects If - Trashing millions of instances/second - Cloning Lots of Lists - Trivial logic - Persistent Entities
  • 45. 213 © VictorRentea.ro a training by Take-Aways ➢ Complex logic ➔ pure functions using immutable objects ➢ Functional Core / Imperative Shell ➢ Pull impure remote/DB calls in the shell ➢ We'll change it in there ➔ compute and return ➢ Without proper mindset, immutability can hurt ➢ Don't mutate: argument state, variables or collections ➢ Immutable: runtime data or persistent leaves ➢ We'll change it in there ➔ compute and return And no, I'm against OOP; but not in huge logic code ➔
  • 46. 214 © VictorRentea.ro a training by victorrentea@gmail.com ♦ ♦ Training: VictorRentea.ro ➢We'll change it in there ➔ compute and return