When something is painful
but you can't avoid doing it…
postpone it
Slide 3
Slide 3 text
When something is painful
but you can't avoid doing it…
delegate it
Slide 4
Slide 4 text
When something is painful
but you can't avoid doing it…
Do It More Often!
"Bring The Pain Forward!"
Slide 5
Slide 5 text
Continuous Integration
Pair Programming
Continuous Refactoring
TDD
XP
"Bring The Pain Forward!"
Slide 6
Slide 6 text
Victor Rentea
14 years of Java
Clean Code Evangelist
VictorRentea.ro
30+ talks, 12 meetups
.NET
Lead Architect
Tech Team Lead and Consultant
Software Craftsman
XP: Pair Programming, Refactoring, TDD
Slide 7
Slide 7 text
VictorRentea.ro @victorrentea [email protected]
Independent
Technical Trainer & Coach
Hibernate
Spring Java 8
Architecture, DDD
Design Patterns
Clean Code Unit Testing, TDD
Java Performance and much more…
Scala
180+ days
1300 devs
6 years
VictorRentea.ro
[email protected]
30 companies
Posting daily on
Slide 8
Slide 8 text
No content
Slide 9
Slide 9 text
No content
Slide 10
Slide 10 text
No content
Slide 11
Slide 11 text
No content
Slide 12
Slide 12 text
26
The most important principle
in programming?
Slide 13
Slide 13 text
27
Single Responsibility Principle
EmployeeManager
-read/persist
-compute pay-roll
-generate PDF report
-manage projects
vs
Slide 14
Slide 14 text
28
Coupling
vs
Slide 15
Slide 15 text
29
Don’t Repeat Yourself
Slide 16
Slide 16 text
30
Keep It Short & Simple
Premature encapsulation is the root of all evil
Overengineering
– Adam Bien
Slide 17
Slide 17 text
31
Keep It Short & Simple
Premature encapsulation is the root of all evil
Overengineering
Simpler code Developer Happiness
Slide 18
Slide 18 text
32
Invisible Magic to reduce effort and risk
Protect the Developers
...
Avoid building an intrusive
Custom Framework
(bugs to learn)
Developer
Comfort
Fear Kills Creativity Simplify Unit Testing
- Strong regression defense
Protect the Developers
34
Developer
Safety
Slide 21
Slide 21 text
Always Think
Regular Brainstorming
35
Continuous Refactoring
There are NO boring tasks
automate them
Slide 22
Slide 22 text
36
Slide 23
Slide 23 text
39
Keep Struggling for a
Can you predict the future ?
What features will grow
super-complex in time?
Simple Design
At all times!
Slide 24
Slide 24 text
40
- Kent Beck
https://martinfowler.com/bliki/BeckDesignRules.html
2. Reveals Intention
3. No Duplication
4. Fewest Elements
1. Passes the Tests
Rules of Simple Design
Slide 25
Slide 25 text
41
A Simple Architecture
that Evolves
to Match
the Growing Complexity
This talk is about…
Slide 26
Slide 26 text
42
Core Principles
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Agenda
VictorRentea.ro
Slide 27
Slide 27 text
You control them!
Entities = your persistent data
43
Entity
They simplify your logic
Slide 28
Slide 28 text
44
Put small bits of
highly reusable
domain logic in your
Domain Entities
public class Customer {
[...]
public String getFullName() {
return firstName + " " + lastName;
}
public void activate(User user) {
if (status != Status.DRAFT) {
throw new IllegalStateException();
}
status = Status.ACTIVE;
activatedBy = user;
activatedDate = new Date();
}
public boolean isActive() {
return status == Status.ACTIVE;
}
public boolean canPlaceOrders() {
return status == Status.ACTIVE && !isBann
}
Slide 29
Slide 29 text
45
activatedBy = user;
activatedDate = new Date();
}
public boolean isActive() {
return status == Status.ACTIVE;
}
public boolean canPlaceOrders() {
return status == Status.ACTIVE && !isBann
}
public void addAddress(Address address) {
address.setCustomer(this);
addresses.add(address);
}
public List getAddresses() {
return Collections.unmodifiableList(
addresses);
}
}
public String toExportString() {
return String.format("%s;%s;%d",
firstName, lastName, isActive()?1:0);
}
BlOAt dAnGeR
Fit
Put small bits of
highly reusable
domain logic in your
Domain Entities
Slide 30
Slide 30 text
Entity
id
46
Small
Immutable
Lombok?
No persistent ID
unlike an Entity
Equal by value
of all fields
Embeddable
In larger entities
Value Object: a grouping of domain data
VO
public class Money {
private final Currency currency;
private final BigDecimal amount;
public Money(Currency currency,
BigDecimal amount) {
this.currency = currency;
this.amount = amount;
}
public Currency getCurrency() {
return currency;
}
public BigDecimal getAmount() {
return amount;
}
public boolean equals(Object other)
{ ... }
}
validate();
Slide 31
Slide 31 text
Then, you start exposing data to UI
(SPA, WS, JSF, desktop)
UI has different goals
They want data structures to match their screens.
Never expose your Entities in your API
47
isDeletable: true
(to show/hide the Delete button)
Slide 32
Slide 32 text
I like dumb DTOs
(you'll see soon why)
public fields ?! ! !..
VO
Entity
id
Logic
public class CustomerDto {
private String fullName;
private String phoneNumber;
private Date birthDate;
public final String getFullName
return fullName;
}
public final void setFullName(S
this.fullName = fullName;
}
public final String getPhoneNum
return phoneNumber;
}
public final void setPhoneNumbe
this.phoneNumber = phoneNumbe
}
public final Date getBirthDate(
return birthDate;
}
public final void setBirthDate(
this.birthDate = birthDate;
}
}
48
Form/Request
View/Response
DTO
SearchCriteria/SearchResult
Data Transfer Objects
DTO
Instead, expose in your API
public class CustomerDto {
public String fullName;
public String phoneNumber;
public Date birthDate;
}
dto.fullName = customer.getFullName();
Slide 33
Slide 33 text
49
Core Principles
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Agenda
Slide 34
Slide 34 text
50
Complex Conversion?
Extract Mappers
VO
Entity
id
DTO
Mapper
Logic
API Domain
CustomerDto dto = new CustomerDto();
dto.fullName = customer.getFullName();
dto.birthDate = customer.getBirthDate();
dto.phoneNumber = customer.getPhoneNumber();
CustomerDto dto = new CustomerDto(customer);
Slide 35
Slide 35 text
61
Start implementing all domain logic in a
Facade
Mapper VO
Entity
id
DTO
Facade
Facade Domain
Service
Domain
Service
Domain Services
This approach is detailed in Java EE Patterns - Rethinking Best Practices, by Adam Bien
Then extract logic into
-To hide complexity: SRP
-For Reuse: DRY
▪ (across Facades or Services)
≈ Application Service
[DDD]
Slide 36
Slide 36 text
63
Keep DTOs out!
(parameters and return types)
Mapper VO
Entity
id
DTO
Facade
Facade Domain
Service
Domain
Service
Domain Services
speak your Domain Model
Convert them to your Domain Objects ASAP
DTOs are fragile
(under enemy control)
* I like them dumb (no methods)
Slide 37
Slide 37 text
Fç
Validate Data
Façade
Convert Data
Implement Logic
Aspects
- Transactions
- Logging
- Exception Handling*
- Access Control*
64
Facade Roles
DTO
Validator
Mapper
Domain
Service
VO
Entity
id
Slide 38
Slide 38 text
65
What do you mean ?
When a class
grows too big
(>~200 lines?)
➔ break it
Extract when it Grows
How?
Look for a good class
name to summarize
some of its methods
Huh? If I find a good name,
I extract? That’s it?
Exactly!
Piece a cake!
A Good
Name
He-he!☺
“There are only two things
hard in programming:
Cache Invalidation and
Naming Things”
Slide 39
Slide 39 text
66
CustomerFacade
saveCustomer()
getCustomer()
searchCustomer()
saveCustomerPreferences()
getCustomerPreferences()
validateAddress()
resetPassword()
checkPassworStrength()
CustomerPreferecesFacade
saveCustomerPreferences()
getCustomerPreferences()
validateAddress()
resetPassword()
checkPassworStrength()
CustomerFacade
saveCustomer()
getCustomer()
searchCustomer()
Extract when it Grows
at the same level of abstraction
Horizontal Splitting
> 300 lines
Slide 40
Slide 40 text
AlertService
CompositeOrder
Service
67
Separation by Layers of Abstraction
OrderService DeliveryService
Extract when it Grows
Vertical Extraction
more abstract,
more higher-level
Slide 41
Slide 41 text
69
Duplication
Pair Programming
Imposed
repeat in .js the validations from .java
Rush/Lazy
Inadvertent
you forget and implement it again
Inter-developer
you didn't knew that was already implemented
bus factor =2
Slide 42
Slide 42 text
Practice
Pair Programming
Slide 43
Slide 43 text
71
Slide 44
Slide 44 text
Developer Comfort
is essential for
Emerging Architectures
Slide 45
Slide 45 text
74
Slide 46
Slide 46 text
75
Core Principles
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Agenda
VictorRentea.ro
Slide 47
Slide 47 text
76
VO
Entity
id
Domain
Service
Domain
Service
What code would you protect?
Put it in the domain module
Priceless
Domain Logic
Domain Objects
domain
Slide 48
Slide 48 text
Façade
DTO
Validator
Mapper
F
application
77
domain
depends on domain
VO
Entity
id
Domain
Service
Domain
Service
Slide 49
Slide 49 text
78
External
Service
DTO
Domain
Service
Domain
Service
domain
Slide 50
Slide 50 text
79
External
Service
DTO
Adapter
Domain
Service
Domain
Service
domain infrastructure
A huge Adapter® Pattern
- Hide their ugly API
- Handle their Exceptions
- Decouple their DTOs your Entities
- Validate their evil data
Slide 51
Slide 51 text
80
External
Service
DTO
IAdapter Adapter
implements
class OrderRepository
implements IOrderRepo {
public Order getById(id){
...
}
}
interface IOrderRepo {
Order getById(id);
}
class OrderService {
@Autowired
IOrderRepository repo;
... {
repo.getById(id);
}
}
express your need in
a domain interface…
and implement it in a
lower-level module…
When you need
to call outside…
so nothing foreign
enters your domain.
Domain
Service
Domain
Service
domain infrastructure
Slide 52
Slide 52 text
81
calls
Dependency Inversion Principle
higher-level
module
lower-level
module
"Best of OOP"
- Uncle Bob
Abstractions should not depend on details
Low level classes
are not visible
Slide 53
Slide 53 text
infra
Adapter
83
External
Service
XML, JSON
IAdapter
implements
HTTP, RMI, …
FTP
JMS
domain
DB
DTO
Slide 54
Slide 54 text
84
Slide 55
Slide 55 text
85
BUT…
Slide 56
Slide 56 text
86
VO
Entity
id
Domain
Service
Domain
Service
IExtSrv
Adapter
IRepo
What code would you protect?
Put it in the domain module
Interfaces for
External Services
you consume
Interfaces for
Repositories
Priceless Domain Logic
Domain Objects
Slide 57
Slide 57 text
infra
ExtSrv
Adapter
Repo
implem
87
Façade
DTO
Validator
Mapper
VO
Entity
id
Domain
Service
Domain
Service
IExtSrv
Adapter
IRepo
F
application
The Onion Architecture
Behold,
a.k.a. Clean, Hexagonal, Ports-and-Adapters
Slide 58
Slide 58 text
98
Façade
DTO
Validator
Mapper
VO
Entity
id
Domain
Service
Domain
Service
IRepo
Repo
implem
F
application
infra
IExtSrv
Adapter
Adapter
WS
Interface
DTO
Slide 59
Slide 59 text
99
Façade
DTO
Validator
Mapper
VO
Entity
id
Domain
Service
Domain
Service
IRepo
Repo
implem
F
application
IExtSrv
Adapter
Adapter
WS
Interface
DTO
domain
Pragmatic
for decent apps, 2 modules are enough
105
coupling
performance
scalability
fitness function
security
source code size
Slide 65
Slide 65 text
108
Core Principles
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Agenda
VictorRentea.ro
Slide 66
Slide 66 text
109
Lots of Unit Tests are Good !
A sense of confidence
Developer Courage
Continuous Refactoring
(It’s still a single )
Slide 67
Slide 67 text
110
As you fight to write Unit Tests,
the Production code gets simpler
Slide 68
Slide 68 text
112
First couple of unit tests : The most valuable
Test no.
difficulty
Slide 69
Slide 69 text
Maintainable Tests
Pure Functions
No side effects. No dependencies.
Mock-based
Less readable
In-memory Emulation
or JPQL tests on H2/* db
Fragile data fixtures
On Real Systems
Eg: Connecting to a real DB
113
, = 2 + 2
Slide 70
Slide 70 text
infrastructure
domain
side effects
116
pure logic
Slide 71
Slide 71 text
▪ 7 Virtutes of a Good Object
▪ NULL – the worst mistake in IT
- https://dzone.com/articles/the-worst-mistake-of-computer-science-1
▪ The Clean Architecture:
- http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
▪ Some ☺ Programming Jargon
- http://blog.codinghorror.com/new-programming-jargon/
▪ Code quality: WTFs/minute
- http://commadot.com/wtf-per-minute/
▪ SOLID is WRONG
- https://speakerdeck.com/tastapod/why-every-element-of-solid-is-wrong
▪ Good software is written 3 times
- http://www.javaworld.com/article/2072651/becoming-a-great-programmer--
use-your-trash-can.html
▪ Prezi-like effect in PowerPoint 2016: “Morph”
▪ Value Objects vs Entity
- http://enterprisecraftsmanship.com/2016/01/11/entity-vs-value-object-the-
ultimate-list-of-differences/
▪ Extends is bad
- http://www.yegor256.com/2016/09/13/inheritance-is-procedural.html
▪ “Measure Don’t Ask” is TM of Kirk Pepperdine
Further Reading
121
Slide 72
Slide 72 text
122
Agenda
VictorRentea.ro
Core Principles
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Slide 73
Slide 73 text
123
Core Principles
VictorRentea.ro
Modeling Data
Organizing Logic
The Onion Architecture
Tests. Fear.
Agenda
Takeaways
Slide 74
Slide 74 text
124 VictorRentea.ro
Tests. Fear.
Organizing Logic
The Onion Architecture
Modeling Data
KISS: Avoid overengineering
Magic to protect your Developers
Takeaways
Slide 75
Slide 75 text
125 VictorRentea.ro
Tests. Fear.
Organizing Logic
The Onion Architecture
Enemy data
KISS: Avoid overengineering
Magic to protect your Developers
in your DTOs: keep them out
Takeaways
Slide 76
Slide 76 text
126 VictorRentea.ro
Tests. Fear.
Extract when it Grows
The Onion Architecture
KISS: Avoid overengineering
Magic to protect your Developers
: for SRP or DRY
Enemy data in your DTOs: keep them out
Takeaways
Slide 77
Slide 77 text
127 VictorRentea.ro
Extract when it Grows
The Onion
KISS: Avoid overengineering
Magic to protect your Developers
: for SRP or DRY
Enemy data in your DTOs: keep them out
, DIP: domain agnostic to externals
Tests. Fear.
Takeaways
(Adapt® them)
Slide 78
Slide 78 text
128 VictorRentea.ro
Extract when it Grows
The Onion
KISS: Avoid overengineering
Magic to protect your Developers
: for SRP or DRY
Enemy data in your DTOs: keep them out
, DIP: domain agnostic to externals
Tests: let them smash your design
Takeaways
(Adapt® them)