SlideShare a Scribd company logo
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

More Related Content

What's hot

Integration testing with spring @snow one
Integration testing with spring @snow oneIntegration testing with spring @snow one
Integration testing with spring @snow one
Victor Rentea
 
Clean code
Clean codeClean code
Clean code
ifnu bima
 
Don't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using MocksDon't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using Mocks
Victor Rentea
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the Domain
Victor Rentea
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Victor Rentea
 
The Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkThe Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring Framework
Victor 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.pptx
Victor Rentea
 
Clean code slide
Clean code slideClean code slide
Clean code slide
Anh Huan Miu
 
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
Victor Rentea
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
José Paumard
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best Practices
Theo Jungeblut
 
Clean code
Clean codeClean code
Clean code
Arturo Herrero
 
Clean code and Code Smells
Clean code and Code SmellsClean code and Code Smells
Clean code and Code Smells
Mario Sangiorgio
 
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
Victor Rentea
 
Clean code
Clean codeClean code
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
John Ferguson Smart Limited
 
Clean code
Clean codeClean code
Clean code
Mahmoud Zizo
 
The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal Architecture
Nicolas Carlo
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
Mattia Battiston
 
Clean Code
Clean CodeClean Code
Clean Code
Hendrik Ebel
 

What's hot (20)

Integration testing with spring @snow one
Integration testing with spring @snow oneIntegration testing with spring @snow one
Integration testing with spring @snow one
 
Clean code
Clean codeClean code
Clean code
 
Don't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using MocksDon't Be Mocked by your Mocks - Best Practices using Mocks
Don't Be Mocked by your Mocks - Best Practices using Mocks
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the Domain
 
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's GuideEvolving a Clean, Pragmatic Architecture - A Craftsman's Guide
Evolving a Clean, Pragmatic Architecture - A Craftsman's Guide
 
The Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring FrameworkThe Proxy Fairy, and The Magic of Spring Framework
The Proxy Fairy, and The Magic of Spring Framework
 
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 code slide
Clean code slideClean code slide
Clean code slide
 
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
 
Asynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFutureAsynchronous API in Java8, how to use CompletableFuture
Asynchronous API in Java8, how to use CompletableFuture
 
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
 
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
 
Clean code
Clean codeClean code
Clean code
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
Clean code
Clean codeClean code
Clean code
 
The Secrets of Hexagonal Architecture
The Secrets of Hexagonal ArchitectureThe Secrets of Hexagonal Architecture
The Secrets of Hexagonal Architecture
 
Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Clean Code
Clean CodeClean Code
Clean Code
 

Similar to 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 2019
Victor 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 2021
David 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.pptx
Victor 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 Programming
Tracy 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 Day2
Daniel Egan
 
Understanding Mocks
Understanding MocksUnderstanding Mocks
Understanding Mocks
Vaidas Pilkauskas
 
DevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation SlidesDevSecCon SG 2018 Fabian Presentation Slides
DevSecCon SG 2018 Fabian Presentation Slides
Fab 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 Data
bobdc
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
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
Melania Andrisan (Danciu)
 
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019Hexagonal Symfony - SymfonyCon Amsterdam 2019
Hexagonal Symfony - SymfonyCon Amsterdam 2019
Matthias Noback
 
Career_camp_professionals.pdf
Career_camp_professionals.pdfCareer_camp_professionals.pdf
Career_camp_professionals.pdf
PrajyotSwami2
 
Rethinking Best Practices
Rethinking Best PracticesRethinking Best Practices
Rethinking Best Practices
floydophone
 
Linq e Ef
Linq e EfLinq e Ef
Linq e Ef
pietrobr
 
Progress of JavaScript Architecture
Progress of JavaScript ArchitectureProgress of JavaScript Architecture
Progress of JavaScript Architecture
Tonya Mork
 
Multi-tenancy with Rails
Multi-tenancy with RailsMulti-tenancy with Rails
Multi-tenancy with Rails
Paul 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 JS
ITCamp
 
Five android architecture
Five android architectureFive android architecture
Five android architecture
Tomislav 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 v2
Enea Gabriel
 

Similar to 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
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
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
 

More from Victor Rentea

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24Microservice Resilience Patterns @VoxxedCern'24
Microservice Resilience Patterns @VoxxedCern'24
Victor Rentea
 
Distributed Consistency.pdf
Distributed Consistency.pdfDistributed Consistency.pdf
Distributed Consistency.pdf
Victor Rentea
 
Testing Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdfTesting Microservices @DevoxxBE 23.pdf
Testing Microservices @DevoxxBE 23.pdf
Victor 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.pptx
Victor Rentea
 
Profiling your Java Application
Profiling your Java ApplicationProfiling your Java Application
Profiling your Java Application
Victor Rentea
 
OAuth in the Wild
OAuth in the WildOAuth in the Wild
OAuth in the Wild
Victor Rentea
 
Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing Architectures
Victor Rentea
 
Unit testing - 9 design hints
Unit testing - 9 design hintsUnit testing - 9 design hints
Unit testing - 9 design hints
Victor Rentea
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
Victor 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 2021
Victor Rentea
 
Hibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the MagicHibernate and Spring - Unleash the Magic
Hibernate and Spring - Unleash the Magic
Victor Rentea
 
Integration testing with spring @JAX Mainz
Integration testing with spring @JAX MainzIntegration testing with spring @JAX Mainz
Integration testing with spring @JAX Mainz
Victor 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 2021
Victor 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 2021
Victor Rentea
 
TDD Mantra
TDD MantraTDD Mantra
TDD Mantra
Victor 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 Objects
Victor 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 Java
Victor Rentea
 

More from Victor Rentea (20)

Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
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
 
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
 
Vertical Slicing Architectures
Vertical Slicing ArchitecturesVertical Slicing Architectures
Vertical Slicing Architectures
 
Unit testing - 9 design hints
Unit testing - 9 design hintsUnit testing - 9 design hints
Unit testing - 9 design hints
 
Extreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software CraftsmanshipExtreme Professionalism - Software Craftsmanship
Extreme Professionalism - Software Craftsmanship
 
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
 

Recently uploaded

LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
lorraineandreiamcidl
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
Green Software Development
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
ISH Technologies
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
Roshan Dwivedi
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
Drona Infotech
 
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdfCodeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Semiosis Software Private Limited
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
mz5nrf0n
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Łukasz Chruściel
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
timtebeek1
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
Gerardo Pardo-Castellote
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
mz5nrf0n
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
Philip Schwarz
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
Fermin Galan
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
Octavian Nadolu
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
pavan998932
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
Hironori Washizaki
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
Paco van Beckhoven
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 

Recently uploaded (20)

LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptxLORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
LORRAINE ANDREI_LEQUIGAN_HOW TO USE WHATSAPP.pptx
 
Energy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina JonuziEnergy consumption of Database Management - Florina Jonuzi
Energy consumption of Database Management - Florina Jonuzi
 
Preparing Non - Technical Founders for Engaging a Tech Agency
Preparing Non - Technical Founders for Engaging  a  Tech AgencyPreparing Non - Technical Founders for Engaging  a  Tech Agency
Preparing Non - Technical Founders for Engaging a Tech Agency
 
Launch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in MinutesLaunch Your Streaming Platforms in Minutes
Launch Your Streaming Platforms in Minutes
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
Mobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona InfotechMobile App Development Company In Noida | Drona Infotech
Mobile App Development Company In Noida | Drona Infotech
 
Codeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdfCodeigniter VS Cakephp Which is Better for Web Development.pdf
Codeigniter VS Cakephp Which is Better for Web Development.pdf
 
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit ParisNeo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
Neo4j - Product Vision and Knowledge Graphs - GraphSummit Paris
 
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
在线购买加拿大英属哥伦比亚大学毕业证本科学位证书原版一模一样
 
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️Need for Speed: Removing speed bumps from your Symfony projects ⚡️
Need for Speed: Removing speed bumps from your Symfony projects ⚡️
 
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdfAutomated software refactoring with OpenRewrite and Generative AI.pptx.pdf
Automated software refactoring with OpenRewrite and Generative AI.pptx.pdf
 
DDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systemsDDS-Security 1.2 - What's New? Stronger security for long-running systems
DDS-Security 1.2 - What's New? Stronger security for long-running systems
 
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
原版定制美国纽约州立大学奥尔巴尼分校毕业证学位证书原版一模一样
 
Hand Rolled Applicative User Validation Code Kata
Hand Rolled Applicative User ValidationCode KataHand Rolled Applicative User ValidationCode Kata
Hand Rolled Applicative User Validation Code Kata
 
Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604Orion Context Broker introduction 20240604
Orion Context Broker introduction 20240604
 
Artificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension FunctionsArtificia Intellicence and XPath Extension Functions
Artificia Intellicence and XPath Extension Functions
 
What is Augmented Reality Image Tracking
What is Augmented Reality Image TrackingWhat is Augmented Reality Image Tracking
What is Augmented Reality Image Tracking
 
SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024SWEBOK and Education at FUSE Okinawa 2024
SWEBOK and Education at FUSE Okinawa 2024
 
Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024Cracking the code review at SpringIO 2024
Cracking the code review at SpringIO 2024
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 

Clean Pragmatic Architecture - Avoiding a Monolith