SlideShare a Scribd company logo
1 of 38
Download to read offline
@lievendoclo#DevoxxPL
Platinum Sponsor:
Implementing Clean
Architecture
Lieven DOCLO
ACA IT Solutions
@lievendoclo#DevoxxPL
• Senior Java Engineer @ ACA
• Software craftsman
• Design and architecture afficionado
Who am I?
www.insaneprogramming.be
@lievendoclo#DevoxxPL
What is this about?
@lievendoclo#DevoxxPL
Clean Architecture?
@lievendoclo#DevoxxPL
• Hexagonal
• Onion
• Screaming
It’s a mixed bag of goodies
@lievendoclo#DevoxxPL
• Core concepts been around for decades
• Got popular by the 2012 article by Robert C. Martin
• A lot of video’s onYouTube
It’s been around for a while
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
@lievendoclo#DevoxxPL
The use cases
@FunctionalInterface
@Boundary
public interface CreateBuilding {
String execute(CreateBuildingRequest request);
}
@Value
public class CreateBuildingRequest {
private final String name;
}
@FunctionalInterface
@Boundary
public interface GetBuilding {
BuildingResponseModel execute(GetBuildingRequest request);
}
@Value
public class BuildingResponseModel {
private final String id;
private final String name;
}
@Value
public class GetBuildingRequest {
private final String buildingId;
}
@lievendoclo#DevoxxPL
Exposing the use case through REST
@RestController
@RequestMapping("/building")
public class BuildingController {
private final CreateBuilding createBuilding;
public BuildingController(CreateBuilding createBuilding) {
this.createBuilding = createBuilding;
}
@PostMapping
public ResponseEntity create(@RequestBody CreateBuildingJsonPayload payload) {
String id = createBuilding.execute(new CreateBuildingRequest(payload.getName()));
return ResponseEntity.created(URI.create("/building/" + id))
.build();
}
}
@lievendoclo#DevoxxPL
Exposing the use case through REST
@GET
@Produces("application/json")
@Path("/{buildingId}")
public BuildingJson get(@PathParam(("buildingId")) String buildingId) {
BuildingResponseModel response = getBuilding.execute(
new GetBuildingRequest(buildingId));
return present(response);
}
public BuildingJson present(BuildingResponseModel buildingResponse) {
return new BuildingJson(buildingResponse.getId(), buildingResponse.getName());
}
@Value
public class BuildingJson {
private final String id;
private final String name;
}
@lievendoclo#DevoxxPL
Exposing the use case through REST
@Immutable
public class BuildingResponseModel {
private final String id;
private final String name;
public <T> T present(Function<BuildingResponseModel, T> presentFunction) {
return presentFunction.apply(this);
}
}
@GET
@Produces("application/json")
@Path("/{buildingId}")
public BuildingJson get(@PathParam(("buildingId")) String buildingId) {
BuildingResponseModel responseModel = getBuilding.execute(
new GetBuildingRequest(buildingId));
return responseModel.present(m ->
new BuildingJson(m.getId(), m.getName()));
}
@lievendoclo#DevoxxPL
• Freedom to choose your exposure
• REST
• JSON-RPC
• SOAP
• Messaging solutions
• …
Exposing the use case
@lievendoclo#DevoxxPL
You can already try this out
@Transactional
@Named
public class CreateBuildingMock implements CreateBuilding {
@Override
public String execute(CreateBuildingRequest request) {
return "42";
}
}
@SpringBootApplication
public class Runner {
public static void main(String[] args) {
SpringApplication.run(Runner.class, args);
}
}
#DevoxxPL @lievendoclo
@lievendoclo#DevoxxPL
Creating the domain
@Value
public class Building {
private final String id;
private final String name;
}
public interface BuildingEntityGateway {
String save(Building building);
Building get(String id);
}
@lievendoclo#DevoxxPL
May the real use case please stand up?
@Transactional
@Named
public class CreateBuildingImpl implements CreateBuilding {
private final BuildingEntityGateway buildingEntityGateway;
public CreateBuildingImpl(BuildingEntityGateway buildingEntityGateway) {
this.buildingEntityGateway = buildingEntityGateway;
}
@Override
public String execute(CreateBuildingRequest request) {
Building building = new Building(null, request.getName());
return buildingEntityGateway.save(building);
}
}
@lievendoclo#DevoxxPL
Again: you can try this out
@Named
public class MockBuildingEntityGateway implements BuildingEntityGateway {
@Override
public String save(Building building) {
return "42";
}
@Override
public Building get(String id) {
return new Building(id, “Acme Corp HQ”);
}
}
@lievendoclo#DevoxxPL
@lievendoclo#DevoxxPL
Implementing the gateway
@Named
public class MongoDbBuildingEntityGateway implements BuildingEntityGateway {
private final Datastore datastore;
public MongoDbBuildingEntityGateway(Datastore datastore) {
this.datastore = datastore;
}
public String save(Building building) {
return datastore.save(
new BuildingDocument(building.getId(), building.getName())
).getId();
}
} @Value
public class BuildingDocument {
@Id
private final String id;
private final String name;
}
@lievendoclo#DevoxxPL
• Once again, complete freedom
• MongoDB
• JPA
• JDBC
• Kafka
• Layering
• Caching
• Calling other API’s (REST or other)
Implementing the gateway
#DevoxxPL @lievendoclo
@lievendoclo#DevoxxPL
• A lot of data structures for a simple write
• Building
• CreateBuildingRequestModel
• CreateBuildingJsonPayload
• BuildingDocument
• When adding reads, it gets worse
• BuildingResponseModel
• JsonBuilding
Decoupling has a price
@lievendoclo#DevoxxPL
@lievendoclo#DevoxxPL
• You can make compromises
• Add JPA annotations on domain
• Add JSON annotations on response

models
• You can expose your use cases through

RPC (decoupling danger)
• Return the domain from the use case

(wouldn’t recommend it tho, decoupling)
• DDD leakage, need to use interfaces on domain
• Your JSON payload extends the use case request model
• Your JSON view model extends the use case response model
Being pragmatic
@lievendoclo#DevoxxPL
• You can make bad compromises
• Add JPA and JSON annotations on domain

and use a single data structure
• Exposing your gateways to the

outside world
• “We’re only doing CRUD anyway!”
Being too pragmatic
@lievendoclo#DevoxxPL
• Compromises are not a bad thing
• Going pure isn’t always the most efficient way forward
• Perfection isn’t always needed or even wanted
• Nice to strive for though
• They can be an acceptable level of technical debt
• But it’s debt nonetheless
• There may come a day someone will collect
• Hint: keep track compromise decisions
Just remember
@lievendoclo#DevoxxPL
Using modular approach
@lievendoclo#DevoxxPL
• Using Kotlin
• Going reactive
• Use event sourcing
Getting all fancy in 2017
interface CreateBuilding {
fun create(request: Mono<CreateBuildingRequest>):
Mono<CreateBuildingResponse>
}
interface GetBuildings {
fun list(): Flux<BuildingResponse>
}
@lievendoclo#DevoxxPL
• Clean Architecture can be evolutionary
• Start off from use cases
• Services
• Go up or down
• Fit for purpose
What about legacy projects?
#TDD
@lievendoclo#DevoxxPL
• More readable code
• Also for business people!
• More maintainable code
• Every layer is easily testable
• Unit tests
• Integration tests
• System tests
• Modular boundaries more easily enforced
So why use Clean Architecture?
@lievendoclo#DevoxxPL
• As little frameworks as possible in inner layers
• Domain logic and business logic, that’s it!
• Choices are made on the outside (infrastructure) layers
• Easy interchangeability
• The main partition does the runtime wiring
• You can choose Spring Boot, Java EE, Dropwizard or OSGi
here
Just remember
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
#DevoxxPL @lievendoclo
https://github.com/lievendoclo/cleanarch

More Related Content

What's hot

A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
Matthias Noback
 
Clean architecture
Clean architectureClean architecture
Clean architecture
andbed
 

What's hot (20)

Real Life Clean Architecture
Real Life Clean ArchitectureReal Life Clean Architecture
Real Life Clean Architecture
 
Clean Architecture
Clean ArchitectureClean Architecture
Clean Architecture
 
Hexagonal architecture for java applications
Hexagonal architecture for java applicationsHexagonal architecture for java applications
Hexagonal architecture for java applications
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)
 
Clean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflixClean pragmatic architecture @ devflix
Clean pragmatic architecture @ devflix
 
Hexagonal architecture
Hexagonal architectureHexagonal architecture
Hexagonal architecture
 
Hexagonal Architecture
Hexagonal ArchitectureHexagonal Architecture
Hexagonal Architecture
 
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
 
A testing strategy for hexagonal applications
A testing strategy for hexagonal applicationsA testing strategy for hexagonal applications
A testing strategy for hexagonal applications
 
The Clean Architecture
The Clean ArchitectureThe Clean Architecture
The Clean Architecture
 
Domain Driven Design 101
Domain Driven Design 101Domain Driven Design 101
Domain Driven Design 101
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Clean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a MonolithClean Pragmatic Architecture - Avoiding a Monolith
Clean Pragmatic Architecture - Avoiding a Monolith
 
Domain Driven Design(DDD) Presentation
Domain Driven Design(DDD) PresentationDomain Driven Design(DDD) Presentation
Domain Driven Design(DDD) Presentation
 
Hexagonal architecture: how, why and when
Hexagonal architecture: how, why and whenHexagonal architecture: how, why and when
Hexagonal architecture: how, why and when
 
Refactoring for Domain Driven Design
Refactoring for Domain Driven DesignRefactoring for Domain Driven Design
Refactoring for Domain Driven Design
 
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
 
Kata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and AdaptersKata: Hexagonal Architecture / Ports and Adapters
Kata: Hexagonal Architecture / Ports and Adapters
 
Hexagonal architecture with Spring Boot
Hexagonal architecture with Spring BootHexagonal architecture with Spring Boot
Hexagonal architecture with Spring Boot
 
The Art of Discovering Bounded Contexts
The Art of Discovering Bounded ContextsThe Art of Discovering Bounded Contexts
The Art of Discovering Bounded Contexts
 

Similar to Clean architecture

Similar to Clean architecture (20)

jDays Sweden 2016
jDays Sweden 2016jDays Sweden 2016
jDays Sweden 2016
 
Java EE revisits design patterns
Java EE revisits design patterns Java EE revisits design patterns
Java EE revisits design patterns
 
Java EE changes design pattern implementation: JavaDays Kiev 2015
Java EE changes design pattern implementation: JavaDays Kiev 2015Java EE changes design pattern implementation: JavaDays Kiev 2015
Java EE changes design pattern implementation: JavaDays Kiev 2015
 
Java EE revisits design patterns
Java EE revisits design patternsJava EE revisits design patterns
Java EE revisits design patterns
 
Java EE Revisits Design Patterns
Java EE Revisits Design PatternsJava EE Revisits Design Patterns
Java EE Revisits Design Patterns
 
SE2016 - Java EE revisits design patterns 2016
SE2016 - Java EE revisits design patterns 2016SE2016 - Java EE revisits design patterns 2016
SE2016 - Java EE revisits design patterns 2016
 
SQL Server 2016 JSON
SQL Server 2016 JSONSQL Server 2016 JSON
SQL Server 2016 JSON
 
Clean Code - Design Patterns and Best Practices at Silicon Valley Code Camp
Clean Code - Design Patterns and Best Practices at Silicon Valley Code CampClean Code - Design Patterns and Best Practices at Silicon Valley Code Camp
Clean Code - Design Patterns and Best Practices at Silicon Valley Code Camp
 
Alex Theedom Java ee revisits design patterns
Alex Theedom	Java ee revisits design patternsAlex Theedom	Java ee revisits design patterns
Alex Theedom Java ee revisits design patterns
 
SE2016 Java Alex Theedom "Java EE revisits design patterns"
SE2016 Java Alex Theedom "Java EE revisits design patterns"SE2016 Java Alex Theedom "Java EE revisits design patterns"
SE2016 Java Alex Theedom "Java EE revisits design patterns"
 
Java EE Revisits GoF Design Patterns
Java EE Revisits GoF Design PatternsJava EE Revisits GoF Design Patterns
Java EE Revisits GoF Design Patterns
 
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
To inject or not to inject - Dependency injection in a Kotlin world (Droidcon...
 
NoSQL Endgame - Java2Days 2020 Virtual
NoSQL Endgame - Java2Days 2020 VirtualNoSQL Endgame - Java2Days 2020 Virtual
NoSQL Endgame - Java2Days 2020 Virtual
 
Devoxx UK 2015: How Java EE has changed pattern implementation
Devoxx UK 2015: How Java EE has changed pattern implementationDevoxx UK 2015: How Java EE has changed pattern implementation
Devoxx UK 2015: How Java EE has changed pattern implementation
 
NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020NoSQL Endgame JCON Conference 2020
NoSQL Endgame JCON Conference 2020
 
EclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL EndgameEclipseCon 2021 NoSQL Endgame
EclipseCon 2021 NoSQL Endgame
 
Docker Tooling for Java EE Developers
Docker Tooling for Java EE  DevelopersDocker Tooling for Java EE  Developers
Docker Tooling for Java EE Developers
 
Angular 2 and NativeScript
Angular 2 and NativeScriptAngular 2 and NativeScript
Angular 2 and NativeScript
 
IoC and Dependency Injection
IoC and Dependency InjectionIoC and Dependency Injection
IoC and Dependency Injection
 
Java One - Designing a DSL in Kotlin
Java One - Designing a DSL in KotlinJava One - Designing a DSL in Kotlin
Java One - Designing a DSL in Kotlin
 

Recently uploaded

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
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
?#DUbAI#??##{{(☎️+971_581248768%)**%*]'#abortion pills for sale in dubai@
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Corporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptxCorporate and higher education May webinar.pptx
Corporate and higher education May webinar.pptx
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 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
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
ICT role in 21st century education and its challenges
ICT role in 21st century education and its challengesICT role in 21st century education and its challenges
ICT role in 21st century education and its challenges
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
+971581248768>> SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHA...
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUKSpring Boot vs Quarkus the ultimate battle - DevoxxUK
Spring Boot vs Quarkus the ultimate battle - DevoxxUK
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 

Clean architecture

  • 2. @lievendoclo#DevoxxPL • Senior Java Engineer @ ACA • Software craftsman • Design and architecture afficionado Who am I? www.insaneprogramming.be
  • 5. @lievendoclo#DevoxxPL • Hexagonal • Onion • Screaming It’s a mixed bag of goodies
  • 6. @lievendoclo#DevoxxPL • Core concepts been around for decades • Got popular by the 2012 article by Robert C. Martin • A lot of video’s onYouTube It’s been around for a while
  • 12. @lievendoclo#DevoxxPL The use cases @FunctionalInterface @Boundary public interface CreateBuilding { String execute(CreateBuildingRequest request); } @Value public class CreateBuildingRequest { private final String name; } @FunctionalInterface @Boundary public interface GetBuilding { BuildingResponseModel execute(GetBuildingRequest request); } @Value public class BuildingResponseModel { private final String id; private final String name; } @Value public class GetBuildingRequest { private final String buildingId; }
  • 13. @lievendoclo#DevoxxPL Exposing the use case through REST @RestController @RequestMapping("/building") public class BuildingController { private final CreateBuilding createBuilding; public BuildingController(CreateBuilding createBuilding) { this.createBuilding = createBuilding; } @PostMapping public ResponseEntity create(@RequestBody CreateBuildingJsonPayload payload) { String id = createBuilding.execute(new CreateBuildingRequest(payload.getName())); return ResponseEntity.created(URI.create("/building/" + id)) .build(); } }
  • 14. @lievendoclo#DevoxxPL Exposing the use case through REST @GET @Produces("application/json") @Path("/{buildingId}") public BuildingJson get(@PathParam(("buildingId")) String buildingId) { BuildingResponseModel response = getBuilding.execute( new GetBuildingRequest(buildingId)); return present(response); } public BuildingJson present(BuildingResponseModel buildingResponse) { return new BuildingJson(buildingResponse.getId(), buildingResponse.getName()); } @Value public class BuildingJson { private final String id; private final String name; }
  • 15. @lievendoclo#DevoxxPL Exposing the use case through REST @Immutable public class BuildingResponseModel { private final String id; private final String name; public <T> T present(Function<BuildingResponseModel, T> presentFunction) { return presentFunction.apply(this); } } @GET @Produces("application/json") @Path("/{buildingId}") public BuildingJson get(@PathParam(("buildingId")) String buildingId) { BuildingResponseModel responseModel = getBuilding.execute( new GetBuildingRequest(buildingId)); return responseModel.present(m -> new BuildingJson(m.getId(), m.getName())); }
  • 16. @lievendoclo#DevoxxPL • Freedom to choose your exposure • REST • JSON-RPC • SOAP • Messaging solutions • … Exposing the use case
  • 17. @lievendoclo#DevoxxPL You can already try this out @Transactional @Named public class CreateBuildingMock implements CreateBuilding { @Override public String execute(CreateBuildingRequest request) { return "42"; } } @SpringBootApplication public class Runner { public static void main(String[] args) { SpringApplication.run(Runner.class, args); } }
  • 19. @lievendoclo#DevoxxPL Creating the domain @Value public class Building { private final String id; private final String name; } public interface BuildingEntityGateway { String save(Building building); Building get(String id); }
  • 20. @lievendoclo#DevoxxPL May the real use case please stand up? @Transactional @Named public class CreateBuildingImpl implements CreateBuilding { private final BuildingEntityGateway buildingEntityGateway; public CreateBuildingImpl(BuildingEntityGateway buildingEntityGateway) { this.buildingEntityGateway = buildingEntityGateway; } @Override public String execute(CreateBuildingRequest request) { Building building = new Building(null, request.getName()); return buildingEntityGateway.save(building); } }
  • 21. @lievendoclo#DevoxxPL Again: you can try this out @Named public class MockBuildingEntityGateway implements BuildingEntityGateway { @Override public String save(Building building) { return "42"; } @Override public Building get(String id) { return new Building(id, “Acme Corp HQ”); } }
  • 23. @lievendoclo#DevoxxPL Implementing the gateway @Named public class MongoDbBuildingEntityGateway implements BuildingEntityGateway { private final Datastore datastore; public MongoDbBuildingEntityGateway(Datastore datastore) { this.datastore = datastore; } public String save(Building building) { return datastore.save( new BuildingDocument(building.getId(), building.getName()) ).getId(); } } @Value public class BuildingDocument { @Id private final String id; private final String name; }
  • 24. @lievendoclo#DevoxxPL • Once again, complete freedom • MongoDB • JPA • JDBC • Kafka • Layering • Caching • Calling other API’s (REST or other) Implementing the gateway
  • 26. @lievendoclo#DevoxxPL • A lot of data structures for a simple write • Building • CreateBuildingRequestModel • CreateBuildingJsonPayload • BuildingDocument • When adding reads, it gets worse • BuildingResponseModel • JsonBuilding Decoupling has a price
  • 28. @lievendoclo#DevoxxPL • You can make compromises • Add JPA annotations on domain • Add JSON annotations on response
 models • You can expose your use cases through
 RPC (decoupling danger) • Return the domain from the use case
 (wouldn’t recommend it tho, decoupling) • DDD leakage, need to use interfaces on domain • Your JSON payload extends the use case request model • Your JSON view model extends the use case response model Being pragmatic
  • 29. @lievendoclo#DevoxxPL • You can make bad compromises • Add JPA and JSON annotations on domain
 and use a single data structure • Exposing your gateways to the
 outside world • “We’re only doing CRUD anyway!” Being too pragmatic
  • 30. @lievendoclo#DevoxxPL • Compromises are not a bad thing • Going pure isn’t always the most efficient way forward • Perfection isn’t always needed or even wanted • Nice to strive for though • They can be an acceptable level of technical debt • But it’s debt nonetheless • There may come a day someone will collect • Hint: keep track compromise decisions Just remember
  • 32. @lievendoclo#DevoxxPL • Using Kotlin • Going reactive • Use event sourcing Getting all fancy in 2017 interface CreateBuilding { fun create(request: Mono<CreateBuildingRequest>): Mono<CreateBuildingResponse> } interface GetBuildings { fun list(): Flux<BuildingResponse> }
  • 33. @lievendoclo#DevoxxPL • Clean Architecture can be evolutionary • Start off from use cases • Services • Go up or down • Fit for purpose What about legacy projects? #TDD
  • 34. @lievendoclo#DevoxxPL • More readable code • Also for business people! • More maintainable code • Every layer is easily testable • Unit tests • Integration tests • System tests • Modular boundaries more easily enforced So why use Clean Architecture?
  • 35. @lievendoclo#DevoxxPL • As little frameworks as possible in inner layers • Domain logic and business logic, that’s it! • Choices are made on the outside (infrastructure) layers • Easy interchangeability • The main partition does the runtime wiring • You can choose Spring Boot, Java EE, Dropwizard or OSGi here Just remember