Professional Documents
Culture Documents
The Art of Clean Code: Enterprise Java Training
The Art of Clean Code: Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
VictorRentea.ro
Agenda
Introduction Why ?!
Names The power invested in you
Functions SRP
Classes The OOP utopia
Comments Incompetence
Clean Lambdas Handling a lightsaber
2 VictorRentea.ro
Victor Rentea
Consultant, Technical Lead
Lead Architect for major IBM client Independent Trainer
1000+ devs. 1500+ hrs. 5 yrs.
Clean Code Evangelist
Spring, JavaEE, JPA/Hibernate
Speaker Clean Code, Architectures
Design Patterns
TDD, Coach, Coding Dojos
Java Performance, more...
victor.rentea@gmail.com @victorrentea VictorRentea.ro
3 VictorRentea.ro
Introduction
Clean Code …
Bjarne Stroustrup
…does one thing well inventor of C++
Grady Booch
…reads like well written prose inventor of UML
Michael Feathers
...was written by someone who cared Working Effectively
with Legacy Code
...when each method you read turns out to be
Ward Cunningham
pretty much what you expected inventor of Wiki, eXtreme Programming
wtf/min
6 VictorRentea.ro
Why Clean Code ?
We READ 10x more time than we WRITE
Make it more readable, even if it’s harder to write
7 VictorRentea.ro
8 VictorRentea.ro
Today, I stopped refactoring.
Today, my application became Legacy.
9 VictorRentea.ro
Agenda
Introduction
Names The power that YOU have
Functions
Classes
Formatting & Comments
Clean Lambdas
11 VictorRentea.ro
Names
12 VictorRentea.ro
Names
?! ?! ?!
green 17 “Mike”
13 VictorRentea.ro
Names
Remoting/API
your-app-api.jar
Strategy Pattern®
Select implementation dynamically at runtime
15 VictorRentea.ro
Names
Rename it !
It takes seconds with an IDE
(and rarely fails: XMLs, reflection,…)
17 VictorRentea.ro
Names
Continuous Renaming
Rename it !
(as you learn the application)
Names should be …
Pronounceable
int getinvcdtlmt()
int getInvoiceableCreditLimit()
Avoid abbreviations !
Unless it’s a basic business concept, like “VAT”
20 VictorRentea.ro
Names should be …
Consistent
.find…() .fetch…() or .get…() ?
Stick to naming conventions
Unique
Synonyms confuse.
Don't use buyer or client to refer to a customer
21 VictorRentea.ro
Business-IT Gap
22 VictorRentea.ro
Agenda
Introduction
Names
Functions Single Responsibility Principle
Classes
Formatting & Comments
Clean Lambdas
26 VictorRentea.ro
Functions
They should be
Small VictorRentea.ro
27
Functions
5 lines
(by any means, smaller than a page of your IDE !)
for
Easy to remember by its author
But for the team, else
if
it's like wilderness
for if
if
29 VictorRentea.ro
Change Request #323
…, boolean cr323)
What do you do ?
EXTRACT
METHODS
if (cr323) {
doOtherStuff();
}
30 VictorRentea.ro
Functions
NO!
Smaller methods run faster !
(get faster)
Just google “Just-In-Time Compiler Optimizations”
31 VictorRentea.ro
Performance ?
32 VictorRentea.ro
Why do small functions scare us?
Instead of a familiar landscape,
else
for if
but,
The Team will thank you !
Even you will be grateful, in 3 months :)
33 VictorRentea.ro
No boolean params => 4
(usually 3)
removeOrders(customer, false, true);
= laziness/fear/rush = legacy
37 VictorRentea.ro
Functions
NULL
(corrupt data)
WARS
File
Defensive Programming
Queue Thoroughly check data
DB only at the boundaries
38 VictorRentea.ro
Unchecked exception
Exceptions won the War !
try
throws
catch (Exception t) {/*Luv U!*/}
We Runtime Exceptions
(‘cause we don’t see them)
My preferences:
Global exception handler try {…} catch (Exception e) { log(e);}
39 VictorRentea.ro
How to write such Functions ?
Continuous Refactoring
all tests
You are not done when the codepass ! working!
starts
41 VictorRentea.ro
An else follows…
public List<Integer> stringsToInts(List<String> strings) {
if (strings != null) {
List<Integer> integers = new ArrayList<>();
for (String s : strings) {
integers.add(Integer.parseInt(s));
}
return integers;
} else {
return null;
}
}
How to simplify it ?
42 VictorRentea.ro
public List<Integer> stringsToInts(List<String> strings) {
if (strings == null) {
return null; Early Return
}
List<Integer> integers = new ArrayList<>();
for (String s : strings) {
integers.add(Integer.parseInt(s));
}
return integers;
}
45 VictorRentea.ro
Agenda
Introduction
Names
Functions
Classes The OOP utopia
Formatting & Comments
Clean Lambdas
46 VictorRentea.ro
struct
(remember the C language ?)
47 VictorRentea.ro
struct
Data structures
=classes that expose all their state
public class SimpleImmutableStruct { public class PhoneBookEntryDTO {
private final String firstName; private String firstName;
private final String lastName; private String lastName;
private String phoneNumber;
public SimpleImmutableStruct(
String first, String last) { public String getFirstName() {
public class PhoneBookEntryDTO {
this.firstName = first; return firstName;
≈
public String firstName;
this.lastName = last; }
public String lastName;
} public void setFirstName(String first) {
public String phoneNumber;
this.firstName = first;
}
public String getFirstName() { }
return firstName;
} public String getLastName() { … }
We getLastName()
public String Immutable {Objects: public void setLastName(…) { … }
- If created valid, remain so
return lastName;
} - Thread safe public String getPhoneNumber() { … }
public void setPhoneNumber(…) { … }
} - Safe to put in Tree*/Hash* }
48 VictorRentea.ro
OOP
49 VictorRentea.ro
Expose Behavior, not data
Data is an implementation detail: it WILL change
car.engineStarted=true
car.setEngineStarted(true)
car.startEngine()
Information Hiding
OOP Tell as little as possible
car.getGasolineInLiters()
car.getPercentageFuelLeft()
car.getEstimatedRemainingKm()
51 VictorRentea.ro
What’s the goal of an Enterprise Application ?
(usually)
To automate an existing business process.
Existing procedures.
Procedural Code
52 VictorRentea.ro
Procedural Code
Lots and lots and lots and lots and lots of it…
53 VictorRentea.ro
Procedural Code
Keep It Short & Simple !!
Yes!
When writing
55 VictorRentea.ro
Agenda
Introduction
Names
Functions
Classes
Formatting & Comments
Clean Lambdas
63 VictorRentea.ro
64 VictorRentea.ro
65 VictorRentea.ro
At work, it’s not Matrix, you know…
It’s Team Work
66 VictorRentea.ro
Don’t Code!
Communicate !
67 VictorRentea.ro
Don’t Code! Communicate !
Respect your readers
Details matter: 10x more reading, remember ?
Write Literature
Always the simplest code that works.
Never obfuscate
VictorRentea.ro
Tune your IDE
Learn those shortcuts !
Static imports
assertEquals(), when(), toList(), emptyList(),…
Super-Fast Deploy
Hot bytecode replace ?
70 etc... VictorRentea.ro
Formatting
Suggestions…
100-120 chars
public class SomeClass {
…
public void someMethod(…) {
5-10 lines 100-200 lines
…
never >1 screen
}
never > 500
… {
} }
Explanatory Variables }
return list1;
73 VictorRentea.ro
Bad Comments
Mumbling Position Markers
- Unclear! stream.close(); //////////////// Accessors ////////////////
} catch (IOException e) {
- Rush/lazy? // Give me a break!
- Forgotten?
} Commented-out Code
Don't read it. Just DELETE IT!
Git rocks!
Redundant
/** Returns the day of the month.
* @return the day of the month.
Non-Local
*/ Comment on that same line !! (±1)
public int getDayOfMonth() {
}
return dayOfMonth; DUH !! Over-involvement
Wiki article syndrome
/** Default constructor. */
74 VictorRentea.ro
Good Comments
Intent: WHY?(what?) TODOs
When the code just can't say it // TODO vrentea Fetch the order
75 VictorRentea.ro
Agenda
Introduction
Names
Functions
Classes
Formatting & Comments
Clean Lambdas
76 VictorRentea.ro
Clean Lambdas
Why Lambdas ?
They are cool
77 VictorRentea.ro
But is the Code Cleaner ?
(than in Java7)
78 VictorRentea.ro
Clean Lambdas
Expressive ?
.filter(MyObj::isActive)
or My own little
Clean Lambdas study
Cryptic ?
.filter(order -> order.getOrderLines().stream()
.filter(line->line.isActive()).findFirst().isPresent())
.map(Order::getOrderLines)
.flatMap(List::stream)
.filter(orderLine -> orderLine.getCount().compareTo(new BigDecimal(“2”))
.collect(groupingBy(OrderLine::getProduct,
groupingBy(line->line.getOrder().getPaymentMethod(),
summingInt(OrderLine::getCount);
79 VictorRentea.ro
.filter(order -> order.getOrderLines().stream()
Avoid breaking lines
.filter(line->line.isActive()).findFirst().isPresent())
.map(Order::getOrderLines)
.flatMap(List::stream)
.collect(groupingBy(OrderLine::getProduct,
groupingBy(line->line.getOrder().getPaymentMethod(),
summingInt(OrderLine::getCount);
80 http://bit.ly/2dFf2fi VictorRentea.ro
Clean Lambdas
Encapsulate Predicates
order.getOrderLines().stream()
.map(Order::getCustomer)
.collect(toSet());
81 http://bit.ly/2dFf2fi VictorRentea.ro
public static Predicate<Order> deliveryDueBefore(Date date) {
Local Variables return order -> order.getDeliveryDueDate().before(date);
}
Functions returning Predicates
Predicate<Order> needsTracking = order -> order.getPrice() > 1000;
Set<Customer> customersToNotify = orders.stream()
.filter(deliveryDueBefore(warningDate).or(needsTracking))
.filter(this::hasLinesNotInStock)
.map(Order::getCustomer)
.collect(toSet());
89 VictorRentea.ro
Peer Review!
Pair Programming
90 VictorRentea.ro
Agenda
Introduction
Names
Functions
Classes
Formatting & Comments
Clean Lambdas
93 VictorRentea.ro
Key Points
Agenda
Stop
Introduction
Refactor = Start Legacy
NamesExpressive Names
Refine
Functions
Short methods
Classes Objects or Logic Containers ?
Structs,
Formattingare
Comments & Comments
Failures. Expressive code.
Clean
Pair Lambdas is the way
Programming
94 VictorRentea.ro
Where
can I read
LET’S
more ?
How to PRACTICE
apply all !!!
this in my
legacy
code
??
98 ©
http://literatejava.com/exception
s/checked-exceptions-javas-
biggest-mistake/
http://stackoverflow.com/questio
ns/613954/the-case-against-
checked-exceptions
7 Virtutes of a Good Object
https://dzone.com/articles/the-
worst-mistake-of-computer-
science-1
http://blog.8thlight.com/uncle-
bob/2012/08/13/the-clean-
architecture.html
http://commadot.com/wtf-per-
minute/
SOLID is WRONG:
https://speakerdeck.com/tastapo
d/why-every-element-of-solid-is-
wrong
Depenency Injection leads to
Clean Code :
https://youtu.be/RlfLCWKxHJ0
99
Check out my tweets for more
VictorRentea.ro
Special Thanks to
JPoint Conference Team,
Ionuţ Chereji, Florin Diaconu
Victor Bucuţea, Ionuţ Scutaru
Laurenţiu Carată, Leonard Giura
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
VictorRentea.ro