SlideShare una empresa de Scribd logo
1 de 80
Descargar para leer sin conexión
REAL 
LIFE
CLEAN ARCHITECTURE
@BattistonMattia
ABOUT ME
●  from Verona, Italy
●  software dev & continuous improvement
●  Kanban, Lean, Agile “helper”
●  Sky Network Services

Mattia Battiston
@BattistonMattia
mattia.battiston@gmail.com
mattia-battiston
DISCLAIMER #1
MICROSERVICES
“Normal” apps
DISCLAIMER #2
THE ONE WAY
Our experience
(pragmatism, tradeoffs)
Infrequent
deploys
COMMON PROBLEMS
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
“
The center of your application
is not the database. Nor is it
one or more of the frameworks
you may be using. 
The center of your application
is the use cases of your
application
Unclebob
Source: NODB
CLEAN ARCHITECTURE
Source: The Clean Architecture
THANK YOU!
THE END
Just Kidding,
The fun is about to
start :-)
EXAMPLE PROJECT
https://github.com/mattia-battiston/clean-architecture-example
EXAMPLE DOMAIN: ISP
Entity:
Telephone 
Exchange
Entity:
Broadband 
Access Device
Use case: 
Get Capacity
“Have we got space for
more customers? Can
we sell more
broadband?”

Use case: 
Reconcile
“Has any physical
device changed?
(e.g. new serial
number)”

Use case: 
Get Details
“Details of a
particular
device?”
OUR CLEAN ARCHITECTURE
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
A.k.a (unclebob’s style)
Entities
Use Cases
Configuration
+
 Core: business logic
Entrypoints: access
to the application
Data Providers:
retrieve and store
information
...
Configuration: wires
everything together
* arrows represent dependency
PROJECT STRUCTURE
ENTITY
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviderscore
ENTITIES
ENTITY
ENTITY
public class Exchange {

private final String code;
private final String name;
private final String postCode;

public Exchange(String code, String name, String postCode) {
this.code = code;
this.name = name;
this.postCode = postCode;
}

// … getters

@Override
public String toString() {
return ...;
}

}
ENTITY
public class BroadbandAccessDevice {

private Exchange exchange;

private String hostname;
private String serialNumber;
private DeviceType type;
private int availablePorts;

public BroadbandAccessDevice(String hostname, ...) {
this.hostname = hostname;
this.serialNumber = serialNumber;
this.type = type;
}

// … (getters, some setters)

@Override
public String toString() {
return ...;
}
}
ENTITY
●  Domain objects
e.g. “Exchange”, “Broadband Access Device”
●  Entity-specific business rules
e.g. hostname format
●  Tiny Types are useful
e.g. Hostname instead of String
●  No Frameworks
USE CASE
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
USE CASES
I
core
USE CASE
USE CASE
public class GetCapacityForExchangeUseCase {

private DoesExchangeExist dataProvider1; 
private GetAvailablePortsOfAllDevicesInExchange dataProvider2;

// … 

public Capacity getCapacity(String exchangeCode) {
failIfExchangeDoesNotExist(exchangeCode);
List<BroadbandAccessDevice> devices = 
dataProvider2
.getAvailablePortsOfAllDevicesInExchange(exchangeCode);
boolean hasAdslCapacity = hasCapacityFor(devices, DeviceType.ADSL);
boolean hasFibreCapacity = hasCapacityFor(devices, DeviceType.FIBRE);
return new Capacity(hasAdslCapacity, hasFibreCapacity);
}

// …

private void failIfExchangeDoesNotExist(String exchangeCode) {
boolean exchangeExists = dataProvider1.doesExchangeExist(exchangeCode);
if(!exchangeExists) throw new ExchangeNotFoundException();
}
}
USE CASE
public interface DoesExchangeExist {
boolean doesExchangeExist(String exchange);
}

public interface GetAvailablePortsOfAllDevicesInExchange {
List<BroadbandAccessDevice> 
getAvailablePortsOfAllDevicesInExchange(String exchangeCode);
}

public class ExchangeNotFoundException extends RuntimeException {
}
USE CASE
●  Pure business logic
e.g. algorithm to calculate capacity
●  Defines Interfaces for the data that it requires
e.g. getAvailablePorts
●  Uses entities and dataproviders
●  Throws business-specific exceptions
●  Not affected by changes in database or presentation
●  Plain Java (no frameworks)
●  We like single-method interfaces 
A.k.a. Interface Segregation
DATA PROVIDER
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
...
dataproviders
DATA PROVIDER
DATA PROVIDER
public class BroadbandAccessDeviceDatabaseDataProvider 
implements GetAllDeviceHostnames, GetSerialNumberFromModel, ... {

private JdbcTemplate jdbcTemplate;

@Override
public List<String> getAllDeviceHostnames() {
return jdbcTemplate.queryForList(
"SELECT hostname FROM clean_architecture.bb_access_device", 
String.class);
}

@Override
public String getSerialNumber(String hostname) {
try {
return jdbcTemplate.queryForObject(

"SELECT serial_number FROM
clean_architecture.bb_access_device 
WHERE hostname = ?", 

String.class, hostname);
} catch (IncorrectResultSizeDataAccessException e) {
return null;
}
}

// …
DATA PROVIDER
public class BroadbandAccessDeviceNetworkDataProvider 
implements GetSerialNumberFromReality {

private DeviceClient deviceClient;

// …

@Override
public String getSerialNumber(String hostname) {
try {
return deviceClient.getSerialNumber(hostname);
} catch (DeviceConnectionTimeoutException e) {
return null;
}
}

}
DATA PROVIDER
●  Implements Interfaces defined by use case
e.g. retrieving serial number of a device
●  Hides all details about where the data is from
●  Could have multiple implementations
e.g. from DB or from File System
●  Uses whatever framework/library is appropriate
e.g. spring-jdbc, hibernate, snmp4j, etc.
●  If using ORM, you’d have a new set of entities
A.k.a. decoupled from business entities
ENTRYPOINT
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
REST APIs
JOBS
...
entrypoints
ENTRYPOINT
ENTRYPOINT
@RestController
public class GetCapacityForExchangeEndpoint {

public static final String API_PATH = "/exchange/{exchangeCode}/capacity";

private GetCapacityForExchangeUseCase getCapacityForExchangeUseCase;

// …

@RequestMapping(value = API_PATH, method = GET)
public CapacityDto getCapacity(@PathVariable String exchangeCode) {
try {
Capacity capacity = 
getCapacityForExchangeUseCase.getCapacity(exchangeCode);
return toDto(capacity);
} catch (ExchangeNotFoundException e) {
LOGGER.info("Exchange not found: {}", exchangeCode);
throw new NotFoundException();
}
}

private CapacityDto toDto(Capacity capacity) {
return new CapacityDto(
capacity.hasAdslCapacity(), capacity.hasFibreCapacity());
}
}
ENTRYPOINT
public class ReconcileBroadbandAccessDeviceJob implements ScheduledJob {

private ReconcileBroadbandAccessDevicesUseCase useCase;
private final JobResults jobResults;

// …

@Override public String getName() { return "..."; }

@Override public long getInitialDelay() { return 0; }

@Override public long getPeriod() { return 5; }

@Override public TimeUnit getTimeUnit() { return TimeUnit.SECONDS; }

@Override
public void run() {
LOGGER.info("Job Starting: {}...", getName());
JobResultsCount jobResultsCount = jobResults.createJobResultsCount();
OnSuccess success = jobResultsCount::success;
OnFailure failure = jobResultsCount::failure;
reconcileBroadbandAccessDevicesUseCase.reconcile(success, failure);
jobResults.recordJobResults(this, jobResultsCount);
LOGGER.info("Job Completed: {}", getName());
}
}
ENTRYPOINT
●  Fires up a use case
●  Has no business logic
●  Has conversion logic 
e.g. uses DTOs to return result to WEB
●  Hides all details about delivery mechanism
●  GUI would be an entrypoint
e.g. controllers would start use cases
●  Uses whatever framework/library is appropriate
e.g. spring-mvc, jersey, quartz, etc.
CONFIGURATION
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
CONFIGURATION
CONFIGURATION
CONFIGURATION
@Configuration
@EnableAutoConfiguration
@ComponentScan(basePackages = "com.clean.example.configuration")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}


@Configuration
public class EndpointConfiguration {
@Bean
public GetBroadbandAccessDeviceEndpoint getBroadbandAccessDeviceEndpoint() {
return new GetBroadbandAccessDeviceEndpoint(...);
}
// …other endpoints… 
}


@Configuration
public class WebServerConfiguration {
// …wires web server with framework… 
}
CONFIGURATION
●  Wires everything together
e.g. using Spring or simply initialising objects
●  Isolates and hides frameworks
e.g. Spring is only here
●  Has the “dirty” details to make things work
e.g. initialise datasource, setup web server, etc.
EXAMPLE: GET CAPACITY
Rest 
Entrypoint
Client
Use 
Case
Data 
Provider
GET /exchange/CHELSEA/capacity
useCase.getCapacity(“CHELSEA”);
dataProvider 
.getAvailablePortsOfAllDevicesInExchange
(”CHELSEA”);
SELECT … WHERE code = “CHELSEA”
return broadbandAccessDevices;
countAvailablePortsOfEachType();
decideIfThereIsCapacity();
return capacity;
convertToDto(capacity);
return dto;
Status Code: 200 OK
{"hasADSLCapacity":true,
"hasFibreCapacity":true}
EXAMPLE: RECONCILE DEVICES
Use Case
Job
Entrypoint
Data Provider:
DB
Data Provider:
Network Device
useCase.reconcile(...);
getAllDeviceHostnames()
 "SELECT hostname...”
// For each device:
getSerialNumberFromModel(hostname)
getSerialNumberFromReality(hostname)
"SELECT serial_number...”
SNMPGET … 
if(serialNumberIsDifferent()) {
updateSerialNumber();
success();
}
auditResults();
Coverage
TESTING STRATEGY
Unit Tests - TDD
Acceptance Tests - BDD
Integration Tests
End-to-end Tests
Manual Exploratory
Tests
Cost
UNIT TESTS
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
UNIT TESTs
UNIT TESTs
UNIT TESTs
UNIT TESTs
UNIT TESTs
UNIT TESTs
UNIT TESTS
// …

GetCapacityForExchangeEndpoint endpoint = // class under test
GetCapacityForExchangeUseCase useCase = // mock

@Test
public void returnsTheCapacityForAnExchange() throws Exception {
givenThereIsCapacityForAnExchange();

CapacityDto capacity = endpoint.getCapacity(EXCHANGE_CODE);

assertThat(capacity.getHasADSLCapacity()).isTrue();
assertThat(capacity.getHasFibreCapacity()).isTrue();
}

private void givenThereIsCapacityForAnExchange() {
when(useCase.getCapacity(EXCHANGE_CODE))
.thenReturn(new Capacity(true, true));
}

// …
UNIT TESTS
●  TDD
A.k.a. Tests first, to drive design
●  Cover every little detail
A.k.a. Aim for 100% coverage
●  “Dev to dev” documentation
A.k.a. What should this class do?
●  Test individual classes in isolation, very fast
ACCEPTANCE TESTS
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
ACC. TESTs
(BUS. REQ.)
ACCEPTANCE TESTS
@Notes("Calculates the remaining capacity in an exchange...")
@LinkingNote(message = "End to End test: %s", links =
{GetCapacityForExchangeEndToEndTest.class})
public class GetCapacityForExchangeAcceptanceTest extends YatspecTest {

// …mock the dependencies of the use case… 

GetCapacityForExchangeUseCase useCase = // …my use case

@Test
public void
hasAdslCapacityWhenThereAreAtLeast5AdslPortsAvailableAcrossAllDevices() {
givenSomeAdslDevicesInTheExchangeWithMoreThan5AdslPortsAvailable();

whenTheCapacityForTheExchangeIsRequested();

thenThereIsAdslCapacity();
}

// … 
}
ACCEPTANCE TESTS
ACCEPTANCE TESTS
●  BDD
A.k.a. Conversations with the business
●  Demonstrate business requirements
A.k.a. Aim to cover business scenarios
●  “Business” documentation
A.k.a. What does the system do? 
●  Test use case in isolation, very fast
A.k.a. No GUI, no DB, etc.
●  Use your favourite BDD framework
We use Yatspec
http
INTEGRATION TESTS
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
INTEGRATION
TESTs
INTEGRATION
TESTs
INTEGRATION TESTS
●  Test integration with slow parts
e.g. Http, database
●  “Dev” documentation
A.k.a. Does this work as expected? 
●  Test one layer in isolation
e.g. only rest endpoint, or only data provider
●  Use whatever library makes it easy
e.g. Spring MockMVC; in-memory db
END-TO-END TESTS
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
http
END-TO-END
TESTs
END-TO-END TESTS
●  Test only the critical journeys
e.g. most common happy path
●  Demonstrate “business” end-to-end requirement
●  Start the whole app, very slow
A.k.a. keep these to a minimum
PRO: TESTING STRATEGY
EFFECTIVE
TESTING STRATEGY
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
PRO: FRAMEWORKS
FRAMEWORKS ARE
ISOLATED
easy(er) to
change our mind
PRO: FRAMEWORKS
ENTITIES
USE CASES
REST APIs
JOBS
DATABASE
FILE SYSTEM
NETWORK
DEVICES
DB
I
...
...
CONFIGURATION
coreentrypoints dataproviders
Spring WEB
Spring boot
Spring jdbc
snmp4j
quartz
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
frameworks
are
Isolated
PRO: DATABASE
INDEPENDENT
FROM DATABASE
PRO: DATABASE
●  No CRUD!
●  RESTful style for reading information
GET /exchange/{exchangeCode}
GET /exchange/{exchangeCode}/capacity
GET /broadbandAccessDevice/{hostname}
●  Custom endpoints for business actions
POST /broadbandAccessDevice/{hostname}/makeLive
PUT /exchange/{exchangeCode}/increaseCapacity
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
frameworks
are
Isolated
PRO: SCREAMING ARCHITECTURE
SCREAMS THE
INTENDED USAGE
PRO: SCREAMING ARCHITECTURE
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
Architecture
frameworks
are
Isolated
PRO: EASY TO FIND THINGS
ALL BUSINESS
LOGIC IS IN 
USE CASE
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
frameworks
are
Isolated
PRO: MODULES
HARD TO DO THE
WRONG THING
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
frameworks
are
Isolated
PRO: ALWAYS READY
ALWAYS READY TO
DEPLOY
real continuous
integration
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
Always
Ready
frameworks
are
Isolated
PRO: SWARMING
PARALLELISE
WORK
multiple pairs on
the same story
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
Always
Ready
Swarming
frameworks
are
Isolated
PRO: NICE MONOLITH
GOOD MONOLITH 
TO START WITH
clear boundaries
to break on
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
Always
Ready
Swarming
frameworks
are
Isolated
Nice
Monolith
CON: DUPLICATION
PERCEIVED
DUPLICATION OF
CODE
be pragmatic
Infrequent
deploys
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
Always
Ready
Swarming
frameworks
are
Isolated
Nice
Monolith
Duplication
CON: IT NEEDS LOGIC
YOU NEED
INTERESTING
BUSINESS LOGIC
CON: IT NEEDS LOGIC
ENDPOINT
// … 
@RequestMapping(value = API_PATH, method = GET)
public BroadbandAccessDeviceDto getDetails(@PathVariable String hostname) {
try {
BroadbandAccessDevice deviceDetails = 
useCase.getDeviceDetails(hostname);
return toDto(deviceDetails);
} catch (DeviceNotFoundException e) {
throw new NotFoundException();
}
}
// … 

USE CASE
// … 
public BroadbandAccessDevice getDeviceDetails(String hostname) {
BroadbandAccessDevice device = dataProvider.getDetails(hostname);
return device;
}
// … 


DATA PROVIDER
// … 
return "SELECT ...";
Infrequent
deploys
Always
Ready
PROBLEMS? FIX!
Decisions
taken
too early
Hard to
change
Centered
around
database
Centered
around
frameworks
Business
logic is
spread
everywhere
Focused
on
technical
aspects
Slow, heavy
tests
Hard to
find things
Effective
Testing
Pyramid
frameworks
are
Isolated
Independent
from
Database
Screaming
ArchitectureAll business
logic in
use cases
Modules
isolate
changes
Nice
Monolith Swarming
Duplication
Needs
Interesting
Logic
KEY TAKEAWAY
“
The center of your application is the
use cases of your application
Unclebob
RESOURCES
Example Project (with all code shown in the presentation)
●  Clean Architecture Example 
https://github.com/mattia-battiston/clean-architecture-example 

Blogs & Articles
●  The Clean Architecture 
https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html
●  Screaming Architecture
http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html
●  NODB 
https://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html
●  Hexagonal Architecture 
http://alistair.cockburn.us/Hexagonal+architecture

Videos & Presentations
●  Clean Coders ep. 7: Architecture, Use Cases, and High Level Design
https://cleancoders.com/episode/clean-code-episode-7/show 
●  Robert C. Martin - Clean Architecture 
https://vimeo.com/43612849
●  Robert C. Martin - Clean Architecture and Design
https://www.youtube.com/watch?v=Nsjsiz2A9mg
really, really appreciated! Help me improve
@BattistonMattia 
mattia.battiston@gmail.com
mattia-battiston
THANK YOU!

Más contenido relacionado

La actualidad más candente

Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootMikalai Alimenkou
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidOutware Mobile
 
Memory Management: What You Need to Know When Moving to Java 8
Memory Management: What You Need to Know When Moving to Java 8Memory Management: What You Need to Know When Moving to Java 8
Memory Management: What You Need to Know When Moving to Java 8AppDynamics
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the DomainVictor Rentea
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Steve Pember
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)Tom Kocjan
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility PrincipleEyal Golan
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean ArchitectureFlavius Stef
 
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 CompletableFutureJosé Paumard
 
Microservices Architecture Part 2 Event Sourcing and Saga
Microservices Architecture Part 2 Event Sourcing and SagaMicroservices Architecture Part 2 Event Sourcing and Saga
Microservices Architecture Part 2 Event Sourcing and SagaAraf Karsh Hamid
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot IntroductionJeevesh Pandey
 
Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootMikalai Alimenkou
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass SlidesNir Kaufman
 
Clean Code I - Best Practices
Clean Code I - Best PracticesClean Code I - Best Practices
Clean Code I - Best PracticesTheo Jungeblut
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applicationsFabricio Epaminondas
 
2012 the clean architecture by Uncle bob
2012 the clean architecture by Uncle bob 2012 the clean architecture by Uncle bob
2012 the clean architecture by Uncle bob GEORGE LEON
 

La actualidad más candente (20)

Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring Boot
 
A Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on AndroidA Separation of Concerns: Clean Architecture on Android
A Separation of Concerns: Clean Architecture on Android
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
Memory Management: What You Need to Know When Moving to Java 8
Memory Management: What You Need to Know When Moving to Java 8Memory Management: What You Need to Know When Moving to Java 8
Memory Management: What You Need to Know When Moving to Java 8
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 
Clean architecture - Protecting the Domain
Clean architecture - Protecting the DomainClean architecture - Protecting the Domain
Clean architecture - Protecting the Domain
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)
 
Single Responsibility Principle
Single Responsibility PrincipleSingle Responsibility Principle
Single Responsibility Principle
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
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
 
Microservices Architecture Part 2 Event Sourcing and Saga
Microservices Architecture Part 2 Event Sourcing and SagaMicroservices Architecture Part 2 Event Sourcing and Saga
Microservices Architecture Part 2 Event Sourcing and Saga
 
Spring boot Introduction
Spring boot IntroductionSpring boot Introduction
Spring boot Introduction
 
Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring Boot
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
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
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applications
 
2012 the clean architecture by Uncle bob
2012 the clean architecture by Uncle bob 2012 the clean architecture by Uncle bob
2012 the clean architecture by Uncle bob
 

Similar a Real Life Clean Architecture

From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)Jose Manuel Pereira Garcia
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatissimonetripodi
 
Don't Make Android Bad... Again
Don't Make Android Bad... AgainDon't Make Android Bad... Again
Don't Make Android Bad... AgainPedro Vicente
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotationjavatwo2011
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureAlexey Buzdin
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android InfrastructureC.T.Co
 
Testing in android
Testing in androidTesting in android
Testing in androidjtrindade
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxpetabridge
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Sven Ruppert
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Networking and Data Access with Eqela
Networking and Data Access with EqelaNetworking and Data Access with Eqela
Networking and Data Access with Eqelajobandesther
 
A portlet-API based approach for application integration
A portlet-API based approach for application integrationA portlet-API based approach for application integration
A portlet-API based approach for application integrationwhabicht
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionChristian Panadero
 
T2 reading 20101126
T2 reading 20101126T2 reading 20101126
T2 reading 20101126Go Tanaka
 
An introduction to Test Driven Development on MapReduce
An introduction to Test Driven Development on MapReduceAn introduction to Test Driven Development on MapReduce
An introduction to Test Driven Development on MapReduceAnanth PackkilDurai
 

Similar a Real Life Clean Architecture (20)

Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)From Legacy to Hexagonal (An Unexpected Android Journey)
From Legacy to Hexagonal (An Unexpected Android Journey)
 
Powerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatisPowerful persistence layer with Google Guice & MyBatis
Powerful persistence layer with Google Guice & MyBatis
 
Don't Make Android Bad... Again
Don't Make Android Bad... AgainDon't Make Android Bad... Again
Don't Make Android Bad... Again
 
比XML更好用的Java Annotation
比XML更好用的Java Annotation比XML更好用的Java Annotation
比XML更好用的Java Annotation
 
Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++Using the Windows 8 Runtime from C++
Using the Windows 8 Runtime from C++
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Overview of Android Infrastructure
Overview of Android InfrastructureOverview of Android Infrastructure
Overview of Android Infrastructure
 
Testing in android
Testing in androidTesting in android
Testing in android
 
SOLID Principles
SOLID PrinciplesSOLID Principles
SOLID Principles
 
NET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptxNET Systems Programming Learned the Hard Way.pptx
NET Systems Programming Learned the Hard Way.pptx
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02
 
Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Networking and Data Access with Eqela
Networking and Data Access with EqelaNetworking and Data Access with Eqela
Networking and Data Access with Eqela
 
Clean coding-practices
Clean coding-practicesClean coding-practices
Clean coding-practices
 
A portlet-API based approach for application integration
A portlet-API based approach for application integrationA portlet-API based approach for application integration
A portlet-API based approach for application integration
 
My way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca editionMy way to clean android - Android day salamanca edition
My way to clean android - Android day salamanca edition
 
T2 reading 20101126
T2 reading 20101126T2 reading 20101126
T2 reading 20101126
 
An introduction to Test Driven Development on MapReduce
An introduction to Test Driven Development on MapReduceAn introduction to Test Driven Development on MapReduce
An introduction to Test Driven Development on MapReduce
 
Having Fun with Play
Having Fun with PlayHaving Fun with Play
Having Fun with Play
 

Más de Mattia Battiston

Agile metrics for predicting the future [2021]
Agile metrics for predicting the future [2021]Agile metrics for predicting the future [2021]
Agile metrics for predicting the future [2021]Mattia Battiston
 
Unlocking your team's potential with pair programming (workshop)
Unlocking your team's potential with pair programming (workshop)Unlocking your team's potential with pair programming (workshop)
Unlocking your team's potential with pair programming (workshop)Mattia Battiston
 
Agile metrics for predicting the future
Agile metrics for predicting the futureAgile metrics for predicting the future
Agile metrics for predicting the futureMattia Battiston
 
Super chickens are not safe
Super chickens are not safeSuper chickens are not safe
Super chickens are not safeMattia Battiston
 
The Science of Happiness [OLD VERSION]
The Science of Happiness [OLD VERSION]The Science of Happiness [OLD VERSION]
The Science of Happiness [OLD VERSION]Mattia Battiston
 
Kanban Metrics in practice for leading Continuous Improvement
Kanban Metrics in practice for leading Continuous ImprovementKanban Metrics in practice for leading Continuous Improvement
Kanban Metrics in practice for leading Continuous ImprovementMattia Battiston
 
Metriche Kanban in pratica a Sky UK [ITA]
Metriche Kanban in pratica a Sky UK [ITA]Metriche Kanban in pratica a Sky UK [ITA]
Metriche Kanban in pratica a Sky UK [ITA]Mattia Battiston
 
Kanban Metrics in practice at Sky Network Services
Kanban Metrics in practice at Sky Network ServicesKanban Metrics in practice at Sky Network Services
Kanban Metrics in practice at Sky Network ServicesMattia Battiston
 

Más de Mattia Battiston (9)

Agile metrics for predicting the future [2021]
Agile metrics for predicting the future [2021]Agile metrics for predicting the future [2021]
Agile metrics for predicting the future [2021]
 
Unlocking your team's potential with pair programming (workshop)
Unlocking your team's potential with pair programming (workshop)Unlocking your team's potential with pair programming (workshop)
Unlocking your team's potential with pair programming (workshop)
 
Agile metrics for predicting the future
Agile metrics for predicting the futureAgile metrics for predicting the future
Agile metrics for predicting the future
 
The Science of Happiness
The Science of HappinessThe Science of Happiness
The Science of Happiness
 
Super chickens are not safe
Super chickens are not safeSuper chickens are not safe
Super chickens are not safe
 
The Science of Happiness [OLD VERSION]
The Science of Happiness [OLD VERSION]The Science of Happiness [OLD VERSION]
The Science of Happiness [OLD VERSION]
 
Kanban Metrics in practice for leading Continuous Improvement
Kanban Metrics in practice for leading Continuous ImprovementKanban Metrics in practice for leading Continuous Improvement
Kanban Metrics in practice for leading Continuous Improvement
 
Metriche Kanban in pratica a Sky UK [ITA]
Metriche Kanban in pratica a Sky UK [ITA]Metriche Kanban in pratica a Sky UK [ITA]
Metriche Kanban in pratica a Sky UK [ITA]
 
Kanban Metrics in practice at Sky Network Services
Kanban Metrics in practice at Sky Network ServicesKanban Metrics in practice at Sky Network Services
Kanban Metrics in practice at Sky Network Services
 

Último

Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineeringssuserb3a23b
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesPhilip Schwarz
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 

Último (20)

Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Odoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting ServiceOdoo Development Company in India | Devintelle Consulting Service
Odoo Development Company in India | Devintelle Consulting Service
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
Software Coding for software engineering
Software Coding for software engineeringSoftware Coding for software engineering
Software Coding for software engineering
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
Folding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a seriesFolding Cheat Sheet #4 - fourth in a series
Folding Cheat Sheet #4 - fourth in a series
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 

Real Life Clean Architecture

  • 2. ABOUT ME ●  from Verona, Italy ●  software dev & continuous improvement ●  Kanban, Lean, Agile “helper” ●  Sky Network Services Mattia Battiston @BattistonMattia mattia.battiston@gmail.com mattia-battiston
  • 4. DISCLAIMER #2 THE ONE WAY Our experience (pragmatism, tradeoffs)
  • 5. Infrequent deploys COMMON PROBLEMS Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things
  • 6. “ The center of your application is not the database. Nor is it one or more of the frameworks you may be using. The center of your application is the use cases of your application Unclebob Source: NODB
  • 7. CLEAN ARCHITECTURE Source: The Clean Architecture
  • 8. THANK YOU! THE END Just Kidding, The fun is about to start :-)
  • 10. EXAMPLE DOMAIN: ISP Entity: Telephone Exchange Entity: Broadband Access Device Use case: Get Capacity “Have we got space for more customers? Can we sell more broadband?” Use case: Reconcile “Has any physical device changed? (e.g. new serial number)” Use case: Get Details “Details of a particular device?”
  • 11. OUR CLEAN ARCHITECTURE ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders
  • 12. A.k.a (unclebob’s style) Entities Use Cases Configuration + Core: business logic Entrypoints: access to the application Data Providers: retrieve and store information ... Configuration: wires everything together * arrows represent dependency
  • 14. ENTITY ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviderscore ENTITIES
  • 16. ENTITY public class Exchange { private final String code; private final String name; private final String postCode; public Exchange(String code, String name, String postCode) { this.code = code; this.name = name; this.postCode = postCode; } // … getters @Override public String toString() { return ...; } }
  • 17. ENTITY public class BroadbandAccessDevice { private Exchange exchange; private String hostname; private String serialNumber; private DeviceType type; private int availablePorts; public BroadbandAccessDevice(String hostname, ...) { this.hostname = hostname; this.serialNumber = serialNumber; this.type = type; } // … (getters, some setters) @Override public String toString() { return ...; } }
  • 18. ENTITY ●  Domain objects e.g. “Exchange”, “Broadband Access Device” ●  Entity-specific business rules e.g. hostname format ●  Tiny Types are useful e.g. Hostname instead of String ●  No Frameworks
  • 19. USE CASE ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders USE CASES I core
  • 21. USE CASE public class GetCapacityForExchangeUseCase { private DoesExchangeExist dataProvider1; private GetAvailablePortsOfAllDevicesInExchange dataProvider2; // … public Capacity getCapacity(String exchangeCode) { failIfExchangeDoesNotExist(exchangeCode); List<BroadbandAccessDevice> devices = dataProvider2 .getAvailablePortsOfAllDevicesInExchange(exchangeCode); boolean hasAdslCapacity = hasCapacityFor(devices, DeviceType.ADSL); boolean hasFibreCapacity = hasCapacityFor(devices, DeviceType.FIBRE); return new Capacity(hasAdslCapacity, hasFibreCapacity); } // … private void failIfExchangeDoesNotExist(String exchangeCode) { boolean exchangeExists = dataProvider1.doesExchangeExist(exchangeCode); if(!exchangeExists) throw new ExchangeNotFoundException(); } }
  • 22. USE CASE public interface DoesExchangeExist { boolean doesExchangeExist(String exchange); } public interface GetAvailablePortsOfAllDevicesInExchange { List<BroadbandAccessDevice> getAvailablePortsOfAllDevicesInExchange(String exchangeCode); } public class ExchangeNotFoundException extends RuntimeException { }
  • 23. USE CASE ●  Pure business logic e.g. algorithm to calculate capacity ●  Defines Interfaces for the data that it requires e.g. getAvailablePorts ●  Uses entities and dataproviders ●  Throws business-specific exceptions ●  Not affected by changes in database or presentation ●  Plain Java (no frameworks) ●  We like single-method interfaces A.k.a. Interface Segregation
  • 24. DATA PROVIDER ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders DATABASE FILE SYSTEM NETWORK DEVICES DB ... dataproviders
  • 26. DATA PROVIDER public class BroadbandAccessDeviceDatabaseDataProvider implements GetAllDeviceHostnames, GetSerialNumberFromModel, ... { private JdbcTemplate jdbcTemplate; @Override public List<String> getAllDeviceHostnames() { return jdbcTemplate.queryForList( "SELECT hostname FROM clean_architecture.bb_access_device", String.class); } @Override public String getSerialNumber(String hostname) { try { return jdbcTemplate.queryForObject( "SELECT serial_number FROM clean_architecture.bb_access_device WHERE hostname = ?", String.class, hostname); } catch (IncorrectResultSizeDataAccessException e) { return null; } } // …
  • 27. DATA PROVIDER public class BroadbandAccessDeviceNetworkDataProvider implements GetSerialNumberFromReality { private DeviceClient deviceClient; // … @Override public String getSerialNumber(String hostname) { try { return deviceClient.getSerialNumber(hostname); } catch (DeviceConnectionTimeoutException e) { return null; } } }
  • 28. DATA PROVIDER ●  Implements Interfaces defined by use case e.g. retrieving serial number of a device ●  Hides all details about where the data is from ●  Could have multiple implementations e.g. from DB or from File System ●  Uses whatever framework/library is appropriate e.g. spring-jdbc, hibernate, snmp4j, etc. ●  If using ORM, you’d have a new set of entities A.k.a. decoupled from business entities
  • 29. ENTRYPOINT ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders REST APIs JOBS ... entrypoints
  • 31. ENTRYPOINT @RestController public class GetCapacityForExchangeEndpoint { public static final String API_PATH = "/exchange/{exchangeCode}/capacity"; private GetCapacityForExchangeUseCase getCapacityForExchangeUseCase; // … @RequestMapping(value = API_PATH, method = GET) public CapacityDto getCapacity(@PathVariable String exchangeCode) { try { Capacity capacity = getCapacityForExchangeUseCase.getCapacity(exchangeCode); return toDto(capacity); } catch (ExchangeNotFoundException e) { LOGGER.info("Exchange not found: {}", exchangeCode); throw new NotFoundException(); } } private CapacityDto toDto(Capacity capacity) { return new CapacityDto( capacity.hasAdslCapacity(), capacity.hasFibreCapacity()); } }
  • 32. ENTRYPOINT public class ReconcileBroadbandAccessDeviceJob implements ScheduledJob { private ReconcileBroadbandAccessDevicesUseCase useCase; private final JobResults jobResults; // … @Override public String getName() { return "..."; } @Override public long getInitialDelay() { return 0; } @Override public long getPeriod() { return 5; } @Override public TimeUnit getTimeUnit() { return TimeUnit.SECONDS; } @Override public void run() { LOGGER.info("Job Starting: {}...", getName()); JobResultsCount jobResultsCount = jobResults.createJobResultsCount(); OnSuccess success = jobResultsCount::success; OnFailure failure = jobResultsCount::failure; reconcileBroadbandAccessDevicesUseCase.reconcile(success, failure); jobResults.recordJobResults(this, jobResultsCount); LOGGER.info("Job Completed: {}", getName()); } }
  • 33. ENTRYPOINT ●  Fires up a use case ●  Has no business logic ●  Has conversion logic e.g. uses DTOs to return result to WEB ●  Hides all details about delivery mechanism ●  GUI would be an entrypoint e.g. controllers would start use cases ●  Uses whatever framework/library is appropriate e.g. spring-mvc, jersey, quartz, etc.
  • 34. CONFIGURATION ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders CONFIGURATION
  • 36. CONFIGURATION @Configuration @EnableAutoConfiguration @ComponentScan(basePackages = "com.clean.example.configuration") public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } } @Configuration public class EndpointConfiguration { @Bean public GetBroadbandAccessDeviceEndpoint getBroadbandAccessDeviceEndpoint() { return new GetBroadbandAccessDeviceEndpoint(...); } // …other endpoints… } @Configuration public class WebServerConfiguration { // …wires web server with framework… }
  • 37. CONFIGURATION ●  Wires everything together e.g. using Spring or simply initialising objects ●  Isolates and hides frameworks e.g. Spring is only here ●  Has the “dirty” details to make things work e.g. initialise datasource, setup web server, etc.
  • 38. EXAMPLE: GET CAPACITY Rest Entrypoint Client Use Case Data Provider GET /exchange/CHELSEA/capacity useCase.getCapacity(“CHELSEA”); dataProvider .getAvailablePortsOfAllDevicesInExchange (”CHELSEA”); SELECT … WHERE code = “CHELSEA” return broadbandAccessDevices; countAvailablePortsOfEachType(); decideIfThereIsCapacity(); return capacity; convertToDto(capacity); return dto; Status Code: 200 OK {"hasADSLCapacity":true, "hasFibreCapacity":true}
  • 39. EXAMPLE: RECONCILE DEVICES Use Case Job Entrypoint Data Provider: DB Data Provider: Network Device useCase.reconcile(...); getAllDeviceHostnames() "SELECT hostname...” // For each device: getSerialNumberFromModel(hostname) getSerialNumberFromReality(hostname) "SELECT serial_number...” SNMPGET … if(serialNumberIsDifferent()) { updateSerialNumber(); success(); } auditResults();
  • 40. Coverage TESTING STRATEGY Unit Tests - TDD Acceptance Tests - BDD Integration Tests End-to-end Tests Manual Exploratory Tests Cost
  • 41. UNIT TESTS ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders UNIT TESTs UNIT TESTs UNIT TESTs UNIT TESTs UNIT TESTs UNIT TESTs
  • 42. UNIT TESTS // … GetCapacityForExchangeEndpoint endpoint = // class under test GetCapacityForExchangeUseCase useCase = // mock @Test public void returnsTheCapacityForAnExchange() throws Exception { givenThereIsCapacityForAnExchange(); CapacityDto capacity = endpoint.getCapacity(EXCHANGE_CODE); assertThat(capacity.getHasADSLCapacity()).isTrue(); assertThat(capacity.getHasFibreCapacity()).isTrue(); } private void givenThereIsCapacityForAnExchange() { when(useCase.getCapacity(EXCHANGE_CODE)) .thenReturn(new Capacity(true, true)); } // …
  • 43. UNIT TESTS ●  TDD A.k.a. Tests first, to drive design ●  Cover every little detail A.k.a. Aim for 100% coverage ●  “Dev to dev” documentation A.k.a. What should this class do? ●  Test individual classes in isolation, very fast
  • 44. ACCEPTANCE TESTS ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders ACC. TESTs (BUS. REQ.)
  • 45. ACCEPTANCE TESTS @Notes("Calculates the remaining capacity in an exchange...") @LinkingNote(message = "End to End test: %s", links = {GetCapacityForExchangeEndToEndTest.class}) public class GetCapacityForExchangeAcceptanceTest extends YatspecTest { // …mock the dependencies of the use case… GetCapacityForExchangeUseCase useCase = // …my use case @Test public void hasAdslCapacityWhenThereAreAtLeast5AdslPortsAvailableAcrossAllDevices() { givenSomeAdslDevicesInTheExchangeWithMoreThan5AdslPortsAvailable(); whenTheCapacityForTheExchangeIsRequested(); thenThereIsAdslCapacity(); } // … }
  • 47. ACCEPTANCE TESTS ●  BDD A.k.a. Conversations with the business ●  Demonstrate business requirements A.k.a. Aim to cover business scenarios ●  “Business” documentation A.k.a. What does the system do? ●  Test use case in isolation, very fast A.k.a. No GUI, no DB, etc. ●  Use your favourite BDD framework We use Yatspec
  • 48. http INTEGRATION TESTS ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders INTEGRATION TESTs INTEGRATION TESTs
  • 49. INTEGRATION TESTS ●  Test integration with slow parts e.g. Http, database ●  “Dev” documentation A.k.a. Does this work as expected? ●  Test one layer in isolation e.g. only rest endpoint, or only data provider ●  Use whatever library makes it easy e.g. Spring MockMVC; in-memory db
  • 50. END-TO-END TESTS ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders http END-TO-END TESTs
  • 51. END-TO-END TESTS ●  Test only the critical journeys e.g. most common happy path ●  Demonstrate “business” end-to-end requirement ●  Start the whole app, very slow A.k.a. keep these to a minimum
  • 53. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid
  • 55. PRO: FRAMEWORKS ENTITIES USE CASES REST APIs JOBS DATABASE FILE SYSTEM NETWORK DEVICES DB I ... ... CONFIGURATION coreentrypoints dataproviders Spring WEB Spring boot Spring jdbc snmp4j quartz
  • 56. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid frameworks are Isolated
  • 58. PRO: DATABASE ●  No CRUD! ●  RESTful style for reading information GET /exchange/{exchangeCode} GET /exchange/{exchangeCode}/capacity GET /broadbandAccessDevice/{hostname} ●  Custom endpoints for business actions POST /broadbandAccessDevice/{hostname}/makeLive PUT /exchange/{exchangeCode}/increaseCapacity
  • 59. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database frameworks are Isolated
  • 62. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming Architecture frameworks are Isolated
  • 63. PRO: EASY TO FIND THINGS ALL BUSINESS LOGIC IS IN USE CASE
  • 64. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases frameworks are Isolated
  • 65. PRO: MODULES HARD TO DO THE WRONG THING
  • 66. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes frameworks are Isolated
  • 67. PRO: ALWAYS READY ALWAYS READY TO DEPLOY real continuous integration
  • 68. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes Always Ready frameworks are Isolated
  • 70. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes Always Ready Swarming frameworks are Isolated
  • 71. PRO: NICE MONOLITH GOOD MONOLITH TO START WITH clear boundaries to break on
  • 72. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes Always Ready Swarming frameworks are Isolated Nice Monolith
  • 74. Infrequent deploys PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes Always Ready Swarming frameworks are Isolated Nice Monolith Duplication
  • 75. CON: IT NEEDS LOGIC YOU NEED INTERESTING BUSINESS LOGIC
  • 76. CON: IT NEEDS LOGIC ENDPOINT // … @RequestMapping(value = API_PATH, method = GET) public BroadbandAccessDeviceDto getDetails(@PathVariable String hostname) { try { BroadbandAccessDevice deviceDetails = useCase.getDeviceDetails(hostname); return toDto(deviceDetails); } catch (DeviceNotFoundException e) { throw new NotFoundException(); } } // … USE CASE // … public BroadbandAccessDevice getDeviceDetails(String hostname) { BroadbandAccessDevice device = dataProvider.getDetails(hostname); return device; } // … DATA PROVIDER // … return "SELECT ...";
  • 77. Infrequent deploys Always Ready PROBLEMS? FIX! Decisions taken too early Hard to change Centered around database Centered around frameworks Business logic is spread everywhere Focused on technical aspects Slow, heavy tests Hard to find things Effective Testing Pyramid frameworks are Isolated Independent from Database Screaming ArchitectureAll business logic in use cases Modules isolate changes Nice Monolith Swarming Duplication Needs Interesting Logic
  • 78. KEY TAKEAWAY “ The center of your application is the use cases of your application Unclebob
  • 79. RESOURCES Example Project (with all code shown in the presentation) ●  Clean Architecture Example https://github.com/mattia-battiston/clean-architecture-example Blogs & Articles ●  The Clean Architecture https://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-architecture.html ●  Screaming Architecture http://blog.8thlight.com/uncle-bob/2011/09/30/Screaming-Architecture.html ●  NODB https://blog.8thlight.com/uncle-bob/2012/05/15/NODB.html ●  Hexagonal Architecture http://alistair.cockburn.us/Hexagonal+architecture Videos & Presentations ●  Clean Coders ep. 7: Architecture, Use Cases, and High Level Design https://cleancoders.com/episode/clean-code-episode-7/show ●  Robert C. Martin - Clean Architecture https://vimeo.com/43612849 ●  Robert C. Martin - Clean Architecture and Design https://www.youtube.com/watch?v=Nsjsiz2A9mg
  • 80. really, really appreciated! Help me improve @BattistonMattia mattia.battiston@gmail.com mattia-battiston THANK YOU!