SlideShare une entreprise Scribd logo
1  sur  102
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Single Responsibility Principle
High Cohesion
A method should do only ONE thing.
A class should have only 1 reason to change..?
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Don’t Repeat Yourself
Never duplicate logic (Capital Sin).
Extract-and-Invoke.
Antonym: Write Everything Twice.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Keep It Short & Simple
Keep It Simple, Stupid - US Navy
Systems work best if kept simple.
Avoid overengineering at all costs.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Loose Coupling
Classes with few dependencies.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
You Ain’t Gonna Need It
Extreme Programming
Don’t add functionality until deemed necessary.
Implement things when you actually need them,
NOT when you just foresee that you need them.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Yoda Conditions
if ("a".equals(param)) {
Avoids NPE. Equals FEAR?
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Favor Composition Over Inheritance
GoF
A extends B is bad.
Use composition: a.setB(b);
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
NOPping
Stanislav sat watching the screensaver
and nopped for a while.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Pair Programming
Two programmers working together on one PC.
The driver writes code, the navigator reviews it.
They switch often.
Is cheaper on long-run.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
Dependency Inversion Principle
Abstractions should not depend on details.
Details should depend on abstractions.
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture
@
VictorRentea.ro
 Spring and
Clean Code, Design Patterns
TDD, Coding Dojos
Java Performance, etc
Victor Rentea
Consultant, Technical Lead
Lead Architect for major IBM client
12
Night Job :
Trainer & CoachClean Code Evangelist
Speaker
victorrentea@gmail.com VictorRentea.ro@victorrentea
VictorRentea.ro13
Driving Principles – KISS
Modeling Data – Enemy data
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Tests. Fear.
Agenda
VictorRentea.ro
@
VictorRentea.ro
Single Responsibility Principle
14
EmployeeManager
-read/persist
-compute pay-roll
-generate PDF report
-manage projects
vs
@
VictorRentea.ro
Coupling
15
vs
Read more: https://dzone.com/articles/probably-the-best-package-structure-in-the-world
@
VictorRentea.ro
Don’t Repeat Yourself
16
@
VictorRentea.ro
Keep It Short & Simple
17
Premature encapsulation is the root of all evilOverengineering
– Adam Bien
@
VictorRentea.ro
Premature encapsulation is the root of all evilOverengineering
Keep It Short & Simple
18
@
VictorRentea.ro
Keep It Short & Simple
19
Premature encapsulation is the root of all evilOverengineering
Less, simple code Developer Happiness 
@
VictorRentea.ro
Invisible Magic to reduce effort and risk
Protect the Developers
20
...
Avoid (yet another)
Custom Framework
(to learn)

Developer
Comfort
VictorRentea.ro21
Request/Thread Scope
@Autowired
private MyRequestContext requestContext;
... {
entity.setModifiedBy(requestContext.getCurrentUser());
}
@Component
@Scope(value = "request", proxyMode = TARGET_CLASS)
class MyRequestContext { ... }
@
VictorRentea.ro
Fear Kills Creativity Simplify Unit Testing
- Strong regression defense
Protect the Developers
22
Developer
Safety
@
VictorRentea.ro
Always Think
Regular Brainstorming
23
Regular Refactoring
@
VictorRentea.ro24
Today, 7 April 2017,
I stopped refactoring.
Today, my application became Legacy
@
VictorRentea.ro
Transaction Script
Procedures working with Anemic Entities
- Map easily to real-world business procedures
Domain Driven Design
Rich Entities (OOP) + many XyzServices
- Requires deep business involvement
- Promises easier maintenance on the long-run
- Harder to learn
25
Data
Logic
Where to implement the domain logic ?
or
So I separate logic from data
VictorRentea.ro26
Driving Principles – KISS
Modeling Data – Enemy data
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Tests. Fear.
Agenda
VictorRentea.ro
@
VictorRentea.ro
You control them!
Entities hold your persistent data
27
Entity
Logic
Use them to simplify the
implementation of your domain logic
@
VictorRentea.ro
Put small bits of highly
reusable
domain logic in your
Domain Entities
28
public class Customer {
// fields, getters and setters, ...
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
}
@
VictorRentea.ro
Put small bits of highly
reusable
domain logic in your
Domain Entities
29
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<Address> getAddresses() {
return Collections.unmodifiableList(
addresses);
}
}
public String toExportString() {
return String.format("%s;%s;%d",
firstName, lastName, isActive()?1:0);
}
BlOAt dAnGeR
Fit
@
VictorRentea.ro
Entityid
Small: Developer Comfort
Immutable: Developer Safety
Transient: no persistent ID/PK (vs Entity)
Value Object: grouping of domain data that move together
30
Logic
VOpublic class Money {
private Currency currency;
private float amount;
// ...
}
public class Money {
private Currency currency;
private BigDecimal amount;
// ...
}
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();
@
VictorRentea.ro
Then, you start building a User Interface (REST, JSF, ...)
But you quickly realize UI is your enemy.
They want data structures to match the screens.
Their goal is different.
Never expose your Entities to them.
31
Order.isDeletable:boolean
(to show/hide
the Delete button)
@
VictorRentea.ro
I personally like them to be dumb
- public fields ?! !!.. Why not? It’s a struct!
VOEntityid
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;
}
}
Form/Request
View/Response
DTO
SearchCriteria/SearchResult
Data Transfer Objects
32
DTO
Instead, give your clients
public class CustomerDto {
public String fullName;
public String phoneNumber;
public Date birthDate;
}
Bare data structures
dto.fullName = customer.getFullName();
Why? You’ll see soon…
VictorRentea.ro33
Driving Principles – KISS
Modeling Data – Enemy data
Organizing Logic
Clean Architecture – The Onion
Tests. Fear.
Agenda
VictorRentea.ro
@
VictorRentea.ro
When DTO  Entity conversion is complex or too long
Extract Mappers to clean up the domain logic
34
VOEntityid
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);
@
VictorRentea.ro
Mappers go to DB ?
KISS: Yes !
35
@
VictorRentea.ro
Mappers go to DB ?
KISS: Yes !
36
public Customer toEntityForCreate(CustomerDto dto) {
Customer customer = new Customer();
customer.setBirthDate(dto.birthDate);
customer.setGroup(groupRepo.getReference(dto.groupId));...
return customer;
}
public CustomerDto toDto(Customer customer) {
CustomerDto dto = new CustomerDto();
dto.birthDate = customer.getBirthDate();
for (Address a:customer.getAddresses()) {
for (Address a:addressRepo.getByCustomer(customer.getId())){
...
}
return dto;
}
}
Link to
DB entities
Actually,
no DB call
Load more
data from DB
public CustomerDto toDto(Customer customer) {
CustomerDto dto = new CustomerDto();
dto.birthDate = customer.getBirthDate();
for (Address a:customer.getAddresses()) {
for (Address a:addressRepo.getByCustomer(customer.getId())){
...
}
return dto;
} … WHERE ADDR.CUSTOMER_ID = ?
Lazy-load with ORM
Explicit load w/o ORM
N+1 Queries
@
VictorRentea.ro37
N+1 Queries
x 1000
@
VictorRentea.ro
Mappers go to DB ?
KISS: Yes !
38
public Customer toEntityForCreate(CustomerDto dto) {
Customer customer = new Customer();
customer.setBirthDate(dto.birthDate);
customer.setGroup(groupRepo.getReference(dto.groupId));...
return customer;
}
public CustomerDto toDto(Customer customer) {
CustomerDto dto = new CustomerDto();
dto.birthDate = customer.getBirthDate();
for (Address a:customer.getAddresses()) {
for (Address a:addressRepo.getByCustomer(customer.getId())){
...
}
return dto;
}
}
Link to
DB entities
… WHERE ADDR.CUSTOMER_ID = ?
Actually,
no DB call
Load more
data from DB
Lazy-load with ORM
public CustomerDto toDto(Customer customer) {
CustomerDto dto = new CustomerDto();
dto.birthDate = customer.getBirthDate();
for (Address a:customer.getAddresses()) {
for (Address a:addressRepo.getByCustomer(customer.getId())){
...
}
return dto;
}
Explicit load w/o ORM
VictorRentea.ro39
public List<CustomerDto> search(CustomerCriteria criteria) {
List<Customer> customers = customerRepo.search(criteria);
return customers.stream()
.map(customerMapper::toDto)
.collect(toList());
}
CLEAN CODE 
public CustomerDto toDto(Customer customer) {
CustomerDto dto = new CustomerDto();
dto.birthDate = customer.getBirthDate();
for (Address a:customer.getAddresses()) {
for (Address a:addressRepo.getByCustomer(customer.getId())){
...
}
return dto;
}
N+1 Queries
No Prophecies.
Simplicity NOW.
JPQL: LEFT JOIN FETCH customer.addresses
SQL: WHERE ADDR.CUSTOMER_ID IN (?,?,…)
(you know the solution)
VictorRentea.ro40
Measure, Don’t Guess®
Premature encapsulation is the root of all evil
– Adam Bien
optimization
– Donald Knuth
Performance ?
@
VictorRentea.ro
Mapper
Abused DTOs are reused in different use cases
- But some fields are not used in some other cases... Which ones ?!..
41
public class CustomerDto {
public String fullName;
public Date birthDate;
public Long groupId;
public UserTime creation;
public UserTime modification;
}
public class CustomerView extends CustCommDto{
public UserTime creation;
public UserTime modification;
}
public class CustomerCommonDto {
public String fullName;
public Date birthDate;
public Long groupId;
}
Strict DTOs don’t have useless fields
- How to avoid duplication ?
DRY
public CustomerCommonDto common;
- Favor Composition over InheritanceGoF (extends is bad)
@
VictorRentea.ro
You are cheating
when’re DRYing code based on a fragile coincidence
42
(on the client side, the data might be interpreted independently)
@
VictorRentea.ro
You are cheating
when’re DRYing code based on a fragile coincidence
43
Extract constants to explain the logic
Don’t make
a constant here
@
VictorRentea.ro
Start implementing domain logic in a Facade
Extract logic into Domain Services
- To hide complexity – SRP / KISS
- For Reuse (across Facades or Services) - DRY
44
Mapper VOEntityid
DTO
Fç
Façade Domain
Service
Domain
Service
Domain Services
@
VictorRentea.ro
Domain Model
45
Mapper VOEntityid
Fç
Façade Domain
Service
Domain
Service
speak your Domain Model
Keep DTOs out of your logic!
Convert them to your Domain
DTO
Fragile, under enemy control
* That’s why I like dumb DTOs
Domain Services
VictorRentea.ro
Fç
Validate Data
Façade
Convert Data
Implement Logic
Aspects
- Transaction
- Logging
- Global Exception Handling*
46
Facade Roles
DTO
Validator
Mapper
Domain
Service
VOEntityid
VictorRentea.ro47
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 group 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”
@
VictorRentea.ro48
CustomerFacade
saveCustomer()
getCustomer()
searchCustomer()
saveCustomerPreferences()
getCustomerPreferences()
validateAddress()
resetPassword()
checkPassworStrength()
CustomerPreferecesFacade
saveCustomerPreferences()
getCustomerPreferences()
validateAddress()
resetPassword()
checkPassworStrength()
CustomerFacade
saveCustomer()
getCustomer()
searchCustomer()
Extract when it Grows
Same level of abstraction
?!!
@
VictorRentea.ro
In L/XL apps: hard to feel opportunities
 Pair programming, design brainstorming
49
OrderService
AlertService
DeliveryService
Extract for Reuse
Separation by Layers of Abstraction
Increase the Bus Factor
@
VictorRentea.ro
Continuous Practice
Pair Programming
@
VictorRentea.ro
Developer Comfort
is essential for
Emerging Architectures
@
VictorRentea.ro52
VictorRentea.ro53
Driving Principles – KISS
Modeling Data – Enemy data
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Tests. Fear.
Agenda
VictorRentea.ro
VictorRentea.ro54
VOEntityid
Domain
Service
Domain
Service
What code would you protect?
Put it in the domain module
Priceless
Domain Logic
Domain Objects
VictorRentea.ro
Façade
DTO
Validator
Mapper
F
application
55
VOEntityid
Domain
Service
Domain
Service
domain
All the other code
depends on domain
VictorRentea.ro56
External
Service
DTO
JAXB
JSON
Domain
Service
Domain
Service
domain
VictorRentea.ro57
External
Service
DTO
JAXB
JSON
Domain
Service
Domain
Service
domain
VictorRentea.ro
ExtServ
Adapter
58
External
Service
DTO
JAXB
JSON
Domain
Service
Domain
Service
domain
VictorRentea.ro59
public class LDAPUserServiceAdapter {
private LdapContext ctx;
...
public LdapUserSearchResult findAccountByAccountName(String ldapSearchBase, String accountName) {
try {
String searchFilter = "(&(objectClass=user)(sAMAccountName={1}))";
SearchControls searchControls = new SearchControls();
searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
NamingEnumeration<SearchResult> results = ctx.search(
ldapSearchBase, searchFilter, new Object[]{accountName} searchControls);
if (!results.hasMoreElements())
return null;
}
SearchResult searchResult = (SearchResult) results.nextElement();
if (results.hasMoreElements()) {
throw new MyAppException(ErrorCode.DUPLICATE_USER_IN_LDAP);
}
return new LdapUserSearchResult(searchResult);
} catch (NamingException e) {
throw new MyAppException(ErrorCode.LDAP_LOOKUP_FAILED);
}
}
}
External Service Adapter
.
.
.
.
.
VictorRentea.ro
infra
ExtServ
Adapter
60
External
Service
DTO
JAXB
JSON
Protect your
Domain Model!
Domain
Service
<dependency>
DTOs might slip
in your domain !
domain
VictorRentea.ro
infra
ExtServ
Adapter
61
External
Service
DTO
JAXB
JSON
Protect your
Domain Model!
Domain
Service
IExtServ
Adapter
<dependency>
implements
DTOs can’t get indomain
VictorRentea.ro
low-level modulehigh-level module
ExtServ
Adapter
62
IExtServ
Adapter
<dependency>
implements
at runtime, calls
Higher level modules should not depend on lower-level modules
class OrderRepository
implements IOrderRepo {
public Order getById() {
...
}
}
interface IOrderRepo {
Order getById();
}
Dependency Inversion Principle
Domain
Serviceclass OrderService {
IOrderRepository repo;
...{
repo.getById(id);
}
}
Speaks your
Domain Model
Spring/CDI/Guice/… will inject it
@Autowired
Implement it outside
VictorRentea.ro
infra
ExtServ
Adapter
63
External
Service
DTO
JAXB
JSON
Protect your
Domain Model!
Domain
Service
IExtServ
Adapter
<dependency>
implements
domain
VictorRentea.ro
infra
ExtServ
Adapter
64
External
Service
DTO
JAXB
JSON
IExtServ
Adapter
<dependency>
implements
domain
VictorRentea.ro
infra
ExtServ
Adapter
65
External
Service
DTO
JAXB
JSON
IExtServ
Adapter
<dependency>
implements
HTTP, RMI, …
FTP
JMS
domain
DB
VictorRentea.ro66
VOEntityid
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
(DB access)
Priceless Domain Logic
Domain Objects
VictorRentea.ro
infra
ExtSrv
Adapter
Repo
implem
67
Façade
DTO
Validator
Mapper
VOEntityid
Domain
Service
Domain
Service
IExtSrv
Adapter
IRepo
F
application
The Onion Architecture
Behold,
a.k.a. Clean, Hexagonal, Ports-and-Adapters
VictorRentea.ro68
infra
Façade
DTO
Validator
Mapper
VOEntityid
Domain
Service
Domain
Service
IExtSrv
Adapter
IRepo
Repo
implem
F
ExtSrv
Adapter
application
The Onion Architecture
Behold,
a.k.a. Clean, Hexagonal, Ports-and-Adapters
VictorRentea.ro69
Hide the persistence!
Clean your Logic!
VictorRentea.ro
public Employee getById(String employeeId) {
String sql = "SELECT id, name, phone FROM employee WHERE id = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, employeeId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
} catch (SQLException e) {
// TODO: something, don't know what..
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO: something, don't know what..
}
}
}
return null;
} Plain Old JDBC (’90-style)
70
Hide the persistence!
Clean your Logic!
VictorRentea.ro
public Employee getById(String employeeId) {
String sql = "SELECT id, name, phone FROM employee WHERE id = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, employeeId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
} catch (SQLException e) {
// TODO: something, don't know what..
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO: something, don't know what..
}
}
}
return null;
}
Plain Old JDBC (’90-style)
public Employee getById(String employeeId) {
return jdbcTemplate.queryForObject(
"SELECT id, name, phone FROM employee WHERE id = ?",
new RowMapper<Employee>() {
public Employee mapRow(ResultSet rs, int rowNum)
throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
},
employeeId);
} Spring’ JdbcTemplate (or similar)
71
Hide the persistence!
Clean your Logic!
VictorRentea.ro
public Employee getById(String employeeId) {
String sql = "SELECT id, name, phone FROM employee WHERE id = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, employeeId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
} catch (SQLException e) {
// TODO: something, don't know what..
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO: something, don't know what..
}
}
}
return null;
}
Plain Old JDBC (’90-style)
public Employee getById(String employeeId) {
return jdbcTemplate.queryForObject(
"SELECT id, name, phone FROM employee WHERE id = ?",
new RowMapper<Employee>() {
public Employee mapRow(ResultSet rs, int rowNum)
throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
},
employeeId);
}
Spring’ JdbcTemplate (or similar)
public interface IOrderRepository {
Employee getEmployeeBasicById(int id);
}
<select id="getEmployeeBasicById" parameterType="int" resultType="Employee">
SELECT id, name, phone_number AS phoneNumber
FROM EMPLOYEES
WHERE ID = #{id}
</select>MyBatis DataMapper
72
Hide the persistence!
Clean your Logic!
VictorRentea.ro
public Employee getById(String employeeId) {
String sql = "SELECT id, name, phone FROM employee WHERE id = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, employeeId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
} catch (SQLException e) {
// TODO: something, don't know what..
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO: something, don't know what..
}
}
}
return null;
}
Plain Old JDBC (’90-style)
public Employee getById(String employeeId) {
return jdbcTemplate.queryForObject(
"SELECT id, name, phone FROM employee WHERE id = ?",
new RowMapper<Employee>() {
public Employee mapRow(ResultSet rs, int rowNum)
throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
},
employeeId);
}
Spring’ JdbcTemplate (or similar)
class IOrderRepository {
Employee getEmployeeBasicById(int id);
}
<select id="getEmployeeBasicById" parameterType="int" resultType="Employee">
SELECT id, name, phone_number AS phoneNumber
FROM EMPLOYEES
WHERE ID = #{id}
</select>
MyBatis DataMapper
public Employee getById(String id) {
List<Employee> list = em.createQuery(
"SELECT e from Employee e where e.id=:id", Employee.class)
.setParameter("id", id)
.getResultList();
if (list.isEmpty()) {
return null;
} else {
return list.get(0);
}
} JPA/Hibernate
73
Hide the persistence!
Clean your Logic!
VictorRentea.ro
public Employee getById(String employeeId) {
String sql = "SELECT id, name, phone FROM employee WHERE id = ?";
Connection conn = null;
try {
conn = dataSource.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, employeeId);
ResultSet rs = ps.executeQuery();
if (rs.next()) {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
} catch (SQLException e) {
// TODO: something, don't know what..
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
// TODO: something, don't know what..
}
}
}
return null;
}
Plain Old JDBC (’90-style)
public Employee getById(String employeeId) {
return jdbcTemplate.queryForObject(
"SELECT id, name, phone FROM employee WHERE id = ?",
new RowMapper<Employee>() {
public Employee mapRow(ResultSet rs, int rowNum)
throws SQLException {
Employee employee = new Employee();
employee.setId(rs.getString(1));
employee.setName(rs.getString(2));
employee.setPhone(rs.getString(3));
return employee;
}
},
employeeId);
}
Spring’ JdbcTemplate (or similar)
class IOrderRepository {
Employee getEmployeeBasicById(int id);
}
<select id="getEmployeeBasicById" parameterType="int" resultType="Employee">
SELECT id, name, phone_number AS phoneNumber
FROM EMPLOYEES
WHERE ID = #{id}
</select>
MyBatis DataMapper
public Employee getById(String id) {
List<Employee> list = em.createQuery(
"SELECT e from Employee e where e.id=:id", Employee.class)
.setParameter("id", id)
.getResultList();
if (list.isEmpty()) {
return null;
} else {
return list.get(0);
}
}
JPA/Hibernate
@Repository
public interface EmployeeRepository
extends JpaRepository<Employee, Integer>,EmployeeRepositoryCustom {
public Employee getById(Integer employeeId);
public Optional<Employee> getByName(String name);
public Long countByName(String name);
@Query("SELECT e FROM Employee e LEFT JOIN FETCH e.projects")
public List<Employee> getAllFetchProjects();
}
Spring Data JPA - our (fine) selection
74
Hide the persistence!
Clean your Logic!
VictorRentea.ro75
Hide the persistence!
Clean your Logic!
VictorRentea.ro76
Hide the persistence!
Clean your Logic!
VictorRentea.ro77
IRepository
Repository
implementation
it’s a better,
Cleaner, Testable
world
Order
Repo
implements
calls
DIP
Hide the persistence!
Clean your Logic!
1 repo/Entity
Split them
when they grow
domain
repo
VictorRentea.ro78
Façade
DTO
Validator
Mapper
VOEntityid
Domain
Service
Domain
Service
IRepo
Repo
implem
F
application
infra
IExtSrv
Adapter ExtSrv
Adapter
WS
Interface
DTO
VictorRentea.ro79
Façade
DTO
Validator
Mapper
VOEntityid
Domain
Service
Domain
Service
IRepo
Repo
implem
F
application
IExtSrv
Adapter ExtSrv
Adapter
WS
Interface
DTO
domain
Pragmatic
for S/M apps, 2 modules might be enough
VictorRentea.ro
api
80
Façade
DTO
Validator
Mapper
VOEntityid
Domain
Service
Domain
Service
IRepo
Repo
implem
F
application
infra
IExtSrv
Adapter ExtSrv
Adapter
WS
Interface
DTO
IFacade
Sent to remote Java clients
persisting knowledge…That’s all I got on architectures
VictorRentea.ro83
Driving Principles – KISS
Modeling Data – Enemy data
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Tests. Fear.
Agenda
VictorRentea.ro
@
VictorRentea.ro
Lots of Unit Tests are Good !
84
A sense of confidence
Developer Courage
Continuous Refactoring
(It’s still a single )
VictorRentea.ro85
As you fight to write Unit Tests,
the Production code gets simpler
@
VictorRentea.ro
Simpler
Decoupled
Live-documented
86
Testable code == Good code
@
VictorRentea.ro87
First couple of unit tests – The most valuable
Test no.
difficulty
@
VictorRentea.ro
Fast tests, Fast feedback
A. Input-output
Pure functions, no side effects. Ideally, no dependencies !
B. Domain logic by mocking dependencies
Less readable tests
C. Queries on a fresh database for each test (in-memory)
Reuse complex test data -> Fragile tests ?
88
𝑓 𝑥, 𝑦 = 𝑥2 + 𝑦2
examples
JavaScript
Unit Tests?
@
VictorRentea.ro
Prod:Test code size
1:3 – 1:10
Short, Readable, Clean tests
@Test(expected = ValidationException.class)
public void withoutNameFails() {
validator.validate(aValidCustomer().withName(null).build());
}
Write Unit Test
is HARD !
@
VictorRentea.ro90
@
VictorRentea.ro
Disclaimer
91
Experience in
Banking, Flavors, ERP and Posting
domains
Mostly Backend Guy
Open-minded Client
(Freedom to architecture)
Projects of size
S-L
VictorRentea.ro92
Driving Principles –
Agenda
VictorRentea.ro
KISS
Modeling Data –
Organizing Logic –
Clean Architecture –
Tests. Fear.
Extract when it Grows
The Onion
Enemy data
VictorRentea.ro93
Driving Principles –
VictorRentea.ro
KISS
Modeling Data –
Organizing Logic –
Clean Architecture –
Tests. Fear.
Extract when it Grows
The Onion
Enemy data
AgendaTakeaways
VictorRentea.ro94 VictorRentea.ro
Tests. Fear.
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Modeling Data – Enemy data
KISS: Avoid overengineering
Magic to protect your Developers
Takeaways
VictorRentea.ro95 VictorRentea.ro
Tests. Fear.
Organizing Logic – Extract when it Grows
Clean Architecture – The Onion
Enemy data
KISS: Avoid overengineering
Magic to protect your Developers
in your DTOs: keep them out
Takeaways
VictorRentea.ro96 VictorRentea.ro
Tests. Fear.
Extract when it Grows
Clean Architecture – The Onion
KISS: Avoid overengineering
Magic to protect your Developers
: for SRP or DRY
Enemy data in your DTOs: keep them out
Takeaways
VictorRentea.ro97 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)
VictorRentea.ro98 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)
VictorRentea.ro99
KISS
VictorRentea.ro100
Keep It simple
101
How to
apply all
this in my
legacy
code
??
Where
can I read
more ?
Show us
more
code !!
©
@
VictorRentea.ro
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”
Further Reading
102
@
VictorRentea.ro103
HUGE Thanks
to the JPoint Reviewers !!
Vladimir Sitnikov
Anton Arhipov
Enterprise Java Training
VictorRentea.ro
victor.rentea@gmail.com
@victorrentea
© Copyright Victor Rentea 2017
Victor Rentea
22 feb 2017
Brainstorming a
Clean Pragmatic Architecture

Contenu connexe

Tendances

Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the DomainVictor Rentea
 
Integration testing with spring @snow one
Integration testing with spring @snow oneIntegration testing with spring @snow one
Integration testing with spring @snow oneVictor Rentea
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxVictor Rentea
 
Clean architecture
Clean architectureClean architecture
Clean architectureLieven Doclo
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code SmellsMario Sangiorgio
 
Unit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityUnit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityVictor Rentea
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean ArchitectureBadoo
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipVictor Rentea
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven DesignYoung-Ho Cho
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean ArchitectureMattia Battiston
 
Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing ArchitecturesVictor Rentea
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionsaber tabatabaee
 
Software Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdfSoftware Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdfVictor Rentea
 

Tendances (20)

Clean Code
Clean CodeClean Code
Clean Code
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the Domain
 
Integration testing with spring @snow one
Integration testing with spring @snow oneIntegration testing with spring @snow one
Integration testing with spring @snow one
 
The tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptxThe tests are trying to tell you something@VoxxedBucharest.pptx
The tests are trying to tell you something@VoxxedBucharest.pptx
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Clean code
Clean codeClean code
Clean code
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
 
Clean Code
Clean CodeClean Code
Clean Code
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
 
Unit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of PurityUnit Testing like a Pro - The Circle of Purity
Unit Testing like a Pro - The Circle of Purity
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Clean code
Clean codeClean code
Clean code
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Clean Code
Clean CodeClean Code
Clean Code
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing Architectures
 
clean code book summary - uncle bob - English version
clean code book summary - uncle bob - English versionclean code book summary - uncle bob - English version
clean code book summary - uncle bob - English version
 
Software Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdfSoftware Craftsmanship @Code Camp Festival 2022.pdf
Software Craftsmanship @Code Camp Festival 2022.pdf
 

Similaire à Clean Pragmatic Architecture - Avoiding a Monolith

Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Victor Rentea
 
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021David Gómez García
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxTest-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxVictor Rentea
 
DevSecCon Singapore 2018 - Remove developers’ shameful secrets or simply rem...
DevSecCon Singapore 2018 -  Remove developers’ shameful secrets or simply rem...DevSecCon Singapore 2018 -  Remove developers’ shameful secrets or simply rem...
DevSecCon Singapore 2018 - Remove developers’ shameful secrets or simply rem...DevSecCon
 
Java Programming
Java ProgrammingJava Programming
Java ProgrammingTracy Clark
 
Daniel Egan Msdn Tech Days Oc Day2
Daniel Egan Msdn Tech Days Oc Day2Daniel Egan Msdn Tech Days Oc Day2
Daniel Egan Msdn Tech Days Oc Day2Daniel Egan
 
DevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation SlidesDevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation SlidesFab L
 
Semantic Web Standards and the Variety “V” of Big Data
Semantic Web Standards and  the Variety “V” of Big DataSemantic Web Standards and  the Variety “V” of Big Data
Semantic Web Standards and the Variety “V” of Big Databobdc
 
Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Melania Andrisan (Danciu)
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Matthias Noback
 
Career_camp_professionals.pdf
Career_camp_professionals.pdfCareer_camp_professionals.pdf
Career_camp_professionals.pdfPrajyotSwami2
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practicesfloydophone
 
Progress of JavaScript Architecture
Progress of JavaScript ArchitectureProgress of JavaScript Architecture
Progress of JavaScript ArchitectureTonya Mork
 
Multi-tenancy with Rails
Multi-tenancy with RailsMulti-tenancy with Rails
Multi-tenancy with RailsPaul Gallagher
 
Mihai Tataran - Building Windows 8 Applications with HTML5 and JS
Mihai Tataran - Building Windows 8 Applications with HTML5 and JSMihai Tataran - Building Windows 8 Applications with HTML5 and JS
Mihai Tataran - Building Windows 8 Applications with HTML5 and JSITCamp
 
Five android architecture
Five android architectureFive android architecture
Five android architectureTomislav Homan
 
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2Enea Gabriel
 

Similaire à Clean Pragmatic Architecture - Avoiding a Monolith (20)

Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
Evolving a Clean, Pragmatic Architecture at JBCNConf 2019
 
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
Builiding Modular monoliths that can scale to microservices. JBCNConf 2021
 
Test-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptxTest-Driven Design Insights@DevoxxBE 2023.pptx
Test-Driven Design Insights@DevoxxBE 2023.pptx
 
DevSecCon Singapore 2018 - Remove developers’ shameful secrets or simply rem...
DevSecCon Singapore 2018 -  Remove developers’ shameful secrets or simply rem...DevSecCon Singapore 2018 -  Remove developers’ shameful secrets or simply rem...
DevSecCon Singapore 2018 - Remove developers’ shameful secrets or simply rem...
 
Java Programming
Java ProgrammingJava Programming
Java Programming
 
Daniel Egan Msdn Tech Days Oc Day2
Daniel Egan Msdn Tech Days Oc Day2Daniel Egan Msdn Tech Days Oc Day2
Daniel Egan Msdn Tech Days Oc Day2
 
Understanding Mocks
Understanding MocksUnderstanding Mocks
Understanding Mocks
 
DevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation SlidesDevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation Slides
 
Semantic Web Standards and the Variety “V” of Big Data
Semantic Web Standards and  the Variety “V” of Big DataSemantic Web Standards and  the Variety “V” of Big Data
Semantic Web Standards and the Variety “V” of Big Data
 
Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017Serverless Single Page Apps with React and Redux at ItCamp 2017
Serverless Single Page Apps with React and Redux at ItCamp 2017
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
 
Career_camp_professionals.pdf
Career_camp_professionals.pdfCareer_camp_professionals.pdf
Career_camp_professionals.pdf
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
 
Linq e Ef
Linq e EfLinq e Ef
Linq e Ef
 
Progress of JavaScript Architecture
Progress of JavaScript ArchitectureProgress of JavaScript Architecture
Progress of JavaScript Architecture
 
Multi-tenancy with Rails
Multi-tenancy with RailsMulti-tenancy with Rails
Multi-tenancy with Rails
 
Mihai Tataran - Building Windows 8 Applications with HTML5 and JS
Mihai Tataran - Building Windows 8 Applications with HTML5 and JSMihai Tataran - Building Windows 8 Applications with HTML5 and JS
Mihai Tataran - Building Windows 8 Applications with HTML5 and JS
 
Five android architecture
Five android architectureFive android architecture
Five android architecture
 
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
Elements of DDD with ASP.NET MVC & Entity Framework Code First v2
 
Coding Naked 2023
Coding Naked 2023Coding Naked 2023
Coding Naked 2023
 

Plus de Victor Rentea

Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24Victor Rentea
 
Distributed Consistency.pdf
Distributed Consistency.pdfDistributed Consistency.pdf
Distributed Consistency.pdfVictor Rentea
 
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening KeynoteClean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening KeynoteVictor Rentea
 
Testing Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdfTesting Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdfVictor Rentea
 
From Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxFrom Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxVictor Rentea
 
Profiling your Java Application
Profiling your Java ApplicationProfiling your Java Application
Profiling your Java ApplicationVictor Rentea
 
Unit testing - 9 design hints
Unit testing - 9 design hintsUnit testing - 9 design hints
Unit testing - 9 design hintsVictor Rentea
 
Refactoring blockers and code smells @jNation 2021
Refactoring   blockers and code smells @jNation 2021Refactoring   blockers and code smells @jNation 2021
Refactoring blockers and code smells @jNation 2021Victor Rentea
 
Hibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the MagicHibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the MagicVictor Rentea
 
Integration testing with spring @JAX Mainz
Integration testing with spring @JAX MainzIntegration testing with spring @JAX Mainz
Integration testing with spring @JAX MainzVictor Rentea
 
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021Victor Rentea
 
Pure functions and immutable objects @dev nexus 2021
Pure functions and immutable objects @dev nexus 2021Pure functions and immutable objects @dev nexus 2021
Pure functions and immutable objects @dev nexus 2021Victor Rentea
 
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Victor Rentea
 
Pure Functions and Immutable Objects
Pure Functions and Immutable ObjectsPure Functions and Immutable Objects
Pure Functions and Immutable ObjectsVictor Rentea
 
Definitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in JavaDefinitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in JavaVictor Rentea
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipVictor Rentea
 
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...Victor Rentea
 

Plus de Victor Rentea (19)

Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24
 
Distributed Consistency.pdf
Distributed Consistency.pdfDistributed Consistency.pdf
Distributed Consistency.pdf
 
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening KeynoteClean Code @Voxxed Days Cluj 2023 - opening Keynote
Clean Code @Voxxed Days Cluj 2023 - opening Keynote
 
Testing Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdfTesting Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdf
 
From Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptxFrom Web to Flux @DevoxxBE 2023.pptx
From Web to Flux @DevoxxBE 2023.pptx
 
Profiling your Java Application
Profiling your Java ApplicationProfiling your Java Application
Profiling your Java Application
 
OAuth in the Wild
OAuth in the WildOAuth in the Wild
OAuth in the Wild
 
Unit testing - 9 design hints
Unit testing - 9 design hintsUnit testing - 9 design hints
Unit testing - 9 design hints
 
Refactoring blockers and code smells @jNation 2021
Refactoring   blockers and code smells @jNation 2021Refactoring   blockers and code smells @jNation 2021
Refactoring blockers and code smells @jNation 2021
 
Hibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the MagicHibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the Magic
 
Integration testing with spring @JAX Mainz
Integration testing with spring @JAX MainzIntegration testing with spring @JAX Mainz
Integration testing with spring @JAX Mainz
 
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
The Proxy Fairy and the Magic of Spring @JAX Mainz 2021
 
Pure functions and immutable objects @dev nexus 2021
Pure functions and immutable objects @dev nexus 2021Pure functions and immutable objects @dev nexus 2021
Pure functions and immutable objects @dev nexus 2021
 
TDD Mantra
TDD MantraTDD Mantra
TDD Mantra
 
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
Definitive Guide to Working With Exceptions in Java - takj at Java Champions ...
 
Pure Functions and Immutable Objects
Pure Functions and Immutable ObjectsPure Functions and Immutable Objects
Pure Functions and Immutable Objects
 
Definitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in JavaDefinitive Guide to Working With Exceptions in Java
Definitive Guide to Working With Exceptions in Java
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
 
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
Engaging Isolation - What I've Learned Delivering 250 Webinar Hours during CO...
 

Dernier

CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceanilsa9823
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...kellynguyen01
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
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.
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 

Dernier (20)

CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female serviceCALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
CALL ON ➥8923113531 🔝Call Girls Badshah Nagar Lucknow best Female service
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
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...
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 

Clean Pragmatic Architecture - Avoiding a Monolith