SlideShare une entreprise Scribd logo
1  sur  28
Télécharger pour lire hors ligne
Keeping business logic out of
your UIs
Petter Holmström, Vaadin Architect
petter@vaadin.com
What is “business logic”?
● Every information system exists to solve a real-world problem (I hope...)
● A real-world problem consists of static parts (things, concepts) and dynamic
parts (events, processes)
● A system uses a model of the real world to solve its problems
○ The domain model
● The static parts of the domain model are often the easy ones
● The dynamic parts are easily forgotten even though they are just as important
● The business logic is the implementation of the dynamic parts of the domain
model
Disclaimer:
Business logic creeping into the
UI is not really an architectural
problem but a problem with
developer discipline
Let’s look at a “classic” architecture
Persistence layer (JPA)
Service layer (EJB)
UI layer (Vaadin)
Entities
SQL database
Problem 1
UI Operation
Service 1
Service 2
Service 3
Actual transaction
boundaries
Logical transaction
boundary
Problem 2
UI CRUD Service+
Business logic in the user’s head and in the UI
Service layer is only a frontend to the database
Problem 3
UI 1
UI 2
UI 3
God Service
Problem 4
Service A Service B
New method
?
What can we do?
Think about the transaction boundary
● Pay attention while coding and while reviewing others’ code
● The transaction boundary should IMO go between the UI and your backend
● Rules of thumb:
○ One UI operation, one backend call
○ One backend call, one transaction
○ One transaction, one thread
● Imagine your backend is running on a remote machine and you want to
minimize the traffic
Take care of your services
● Strive for highly cohesive services
● Avoid too general names like CustomerService
● Instead, opt for more specific names like CustomerOnboarding
● If you are adding a new service method and you find you could add it to more
than one service, you should probably create a completely new one or refactor
the existing ones
Separate reading and writing
● Place your queries in separate components
● Create UI specific query components instead of adding more and more query
methods to existing ones
● Allows for some neat optimizations and scaling
Avoid CRUD
● CRUD UIs and services basically move the business logic into the head of the
user
● Base your UIs and services on actual business processes and operations
● Exception: management UIs for reference and master data
Introducing a
Command based
architecture
● Think in terms of Commands and Queries
● A Command tells the system to perform a specific business operation
○ A command may return some result
○ A command either completes successfully or fails with an error
● A Query asks the system for specific data
○ A query always returns something
○ A query only fails because of external runtime errors such as network problems
● Commands and queries can be synchronous or asynchronous
● You can model each command and each query as a separate class
Forget about services!
The query/command class
● The name is always a verb in its imperative form
● The parameters are class attributes
● Use a generic parameter for the result, if any
● Try to make your class immutable
○ Not always possible, e.g. if you are binding a form directly to your command
● Validate the parameters inside your class
○ If you do this in the constructor, you cannot create a command or query with invalid parameters
Examples
<<command>>
CreatePatient<Patient>
firstName: string
lastName: string
gender: Gender
birthDate: LocalDate
<<query>>
FindOrders<List<Order>>
from: LocalDate
to: LocalDate
customer: Optional<Customer>
Examples (code)
public class CreatePatient implements Command<Patient> {
final String firstName;
final String lastName;
final Gender gender;
final LocalDate birthDate;
public CreatePatient(String firstName, String lastname,
Gender gender, LocalDate birthDate) {
this.firstName = Objects.requireNonNull(firstName);
…
}
}
Examples (code)
public class FindOrders implements Query<List<Order>> {
final LocalDate from;
final LocalDate to;
final Optional<Customer> customer;
public FindOrders(LocalDate from, LocalDate to) {
…
}
public FindOrders(LocalDate from, LocalDate to,
Customer customer) {
…
}
}
What about the implementation?
● Technically, queries and commands are implemented in the same way
● Each command/query has a handler
● The handler contains a single method that accepts the command/query as a
single parameter and returns the result of the command/query
● Handlers are transactional
● Similar queries/commands can share a common base class
● Handlers can invoke other handlers
Finding the correct handler
● A client will never invoke another handler directly
● Instead, commands/queries are passed to a broker or gateway
● The broker/gateway will look up the correct handler, invoke it and return the
result
Advantages
● An easy way of modeling the dynamics of the problem domain
● Forces you to think in terms of the domain while designing your UI
○ Since your UI should only be constructing and invoking commands/queries, the risk of business
logic ending up there should be smaller (I hope)
● Your business logic consists of small, highly cohesive classes
● No more god classes
● Easy to distribute, e.g. by using a service bus
○ Command and queries could be serialized into JSON
○ Command and query handlers can be running anywhere
● Easy to run asynchronously
● You can use separate data sources for reading and writing
○ CQRS
Master SlaveSlave
Query Handler Query Handler
Command
Handler
Broker
UI
Disadvantages
● More boilerplate code: for each operation, you have to write a command/query
class and a handler class
● The client does not invoke the handler directly so if the handler is missing, it
will not be detected until during runtime
● You have to write the command/query framework yourself
● You can still write too coarse or too fine grained commands
Time for a code
example!
What about long-running transactions?
● Many commands participate in the same conversation
● If your container supports it, you can make your handlers conversation scoped
○ This makes it possible to store state in the handlers
● If you want your handlers to remain stateless, create a conversation object that
is returned by and passed to every command handler
● The conversation object contains the state necessary to move the
conversation forward
Summary
● Discipline vs patterns
● Transaction boundary
● High cohesion
● Separate read and write
● Avoid CRUD
● Consider using commands and queries in business driven user interfaces
That’s all folks!

Contenu connexe

Tendances

An Overview of automated testing (1)
An Overview of automated testing (1)An Overview of automated testing (1)
An Overview of automated testing (1)
Rodrigo Lopes
 
Computational thinking
Computational thinkingComputational thinking
Computational thinking
r123457
 

Tendances (20)

Mocking in python
Mocking in pythonMocking in python
Mocking in python
 
An Overview of automated testing (1)
An Overview of automated testing (1)An Overview of automated testing (1)
An Overview of automated testing (1)
 
Overview of Testing Talks at Pycon
Overview of Testing Talks at PyconOverview of Testing Talks at Pycon
Overview of Testing Talks at Pycon
 
@LinkingNote annotation in YATSPEC
@LinkingNote annotation in YATSPEC@LinkingNote annotation in YATSPEC
@LinkingNote annotation in YATSPEC
 
Effective Unit Testing
Effective Unit TestingEffective Unit Testing
Effective Unit Testing
 
Cuis smalltalk past present and future
Cuis smalltalk past present and futureCuis smalltalk past present and future
Cuis smalltalk past present and future
 
Lessons Learned When Automating
Lessons Learned When AutomatingLessons Learned When Automating
Lessons Learned When Automating
 
Delhi second draft
Delhi second draft Delhi second draft
Delhi second draft
 
Code Quality with Magento 2
Code Quality with Magento 2Code Quality with Magento 2
Code Quality with Magento 2
 
Delhi first draft_2
Delhi first draft_2Delhi first draft_2
Delhi first draft_2
 
Unit Testing and TDD 2017
Unit Testing and TDD 2017Unit Testing and TDD 2017
Unit Testing and TDD 2017
 
xUnit test patterns 0
xUnit test patterns 0xUnit test patterns 0
xUnit test patterns 0
 
An Introduction To Software Development - Test Driven Development, Part 1
An Introduction To Software Development - Test Driven Development, Part 1An Introduction To Software Development - Test Driven Development, Part 1
An Introduction To Software Development - Test Driven Development, Part 1
 
The working architecture of NodeJs applications
The working architecture of NodeJs applicationsThe working architecture of NodeJs applications
The working architecture of NodeJs applications
 
Codeception @ New Business Dept Adira Finance
Codeception @ New Business Dept Adira FinanceCodeception @ New Business Dept Adira Finance
Codeception @ New Business Dept Adira Finance
 
Computational thinking
Computational thinkingComputational thinking
Computational thinking
 
DevOps Anti-Patterns
DevOps Anti-PatternsDevOps Anti-Patterns
DevOps Anti-Patterns
 
Tdd in swift
Tdd in swiftTdd in swift
Tdd in swift
 
Test-Driven Development (TDD) in Swift
Test-Driven Development (TDD) in SwiftTest-Driven Development (TDD) in Swift
Test-Driven Development (TDD) in Swift
 
Open source tools - Test Management Summit - 2009
Open source tools - Test Management Summit - 2009Open source tools - Test Management Summit - 2009
Open source tools - Test Management Summit - 2009
 

Similaire à Keeping business logic out of your UIs

Similaire à Keeping business logic out of your UIs (20)

Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"Viktor Turskyi "Effective NodeJS Application Development"
Viktor Turskyi "Effective NodeJS Application Development"
 
From class to architecture
From class to architectureFrom class to architecture
From class to architecture
 
The working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор ТурскийThe working architecture of NodeJS applications, Виктор Турский
The working architecture of NodeJS applications, Виктор Турский
 
The working architecture of node js applications open tech week javascript ...
The working architecture of node js applications   open tech week javascript ...The working architecture of node js applications   open tech week javascript ...
The working architecture of node js applications open tech week javascript ...
 
'Effective node.js development' by Viktor Turskyi at OdessaJS'2020
'Effective node.js development' by Viktor Turskyi at OdessaJS'2020'Effective node.js development' by Viktor Turskyi at OdessaJS'2020
'Effective node.js development' by Viktor Turskyi at OdessaJS'2020
 
DDD with Behat
DDD with BehatDDD with Behat
DDD with Behat
 
Designing salesforce solutions for reuse - Josh Dennis
Designing salesforce solutions for reuse - Josh DennisDesigning salesforce solutions for reuse - Josh Dennis
Designing salesforce solutions for reuse - Josh Dennis
 
Keeping code clean
Keeping code cleanKeeping code clean
Keeping code clean
 
OutSystems Tips and Tricks
OutSystems Tips and TricksOutSystems Tips and Tricks
OutSystems Tips and Tricks
 
Baby steps to Domain-Driven Design
Baby steps to Domain-Driven DesignBaby steps to Domain-Driven Design
Baby steps to Domain-Driven Design
 
Advanced web application architecture - Talk
Advanced web application architecture - TalkAdvanced web application architecture - Talk
Advanced web application architecture - Talk
 
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
Enterprise PHP Architecture through Design Patterns and Modularization (Midwe...
 
Sharable of qualities of clean code
Sharable of qualities of clean codeSharable of qualities of clean code
Sharable of qualities of clean code
 
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
Taming the Legacy Beast: Turning wild old code into a sleak new thoroughbread.
 
Intro to ember.js
Intro to ember.jsIntro to ember.js
Intro to ember.js
 
Clean architecture
Clean architectureClean architecture
Clean architecture
 
Microservices patterns
Microservices patternsMicroservices patterns
Microservices patterns
 
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
Carlo Bonamico, Sonia Pini - So you want to build your (Angular) Component Li...
 
Build Your Own Angular Component Library
Build Your Own Angular Component LibraryBuild Your Own Angular Component Library
Build Your Own Angular Component Library
 
Design Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best PracticesDesign Like a Pro: Scripting Best Practices
Design Like a Pro: Scripting Best Practices
 

Dernier

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Dernier (20)

TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
10 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 202410 Trends Likely to Shape Enterprise Technology in 2024
10 Trends Likely to Shape Enterprise Technology in 2024
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdfThe Top App Development Trends Shaping the Industry in 2024-25 .pdf
The Top App Development Trends Shaping the Industry in 2024-25 .pdf
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand%in Midrand+277-882-255-28 abortion pills for sale in midrand
%in Midrand+277-882-255-28 abortion pills for sale in midrand
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
Microsoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdfMicrosoft AI Transformation Partner Playbook.pdf
Microsoft AI Transformation Partner Playbook.pdf
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 
ManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide DeckManageIQ - Sprint 236 Review - Slide Deck
ManageIQ - Sprint 236 Review - Slide Deck
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 

Keeping business logic out of your UIs

  • 1. Keeping business logic out of your UIs Petter Holmström, Vaadin Architect petter@vaadin.com
  • 2. What is “business logic”? ● Every information system exists to solve a real-world problem (I hope...) ● A real-world problem consists of static parts (things, concepts) and dynamic parts (events, processes) ● A system uses a model of the real world to solve its problems ○ The domain model ● The static parts of the domain model are often the easy ones ● The dynamic parts are easily forgotten even though they are just as important ● The business logic is the implementation of the dynamic parts of the domain model
  • 3. Disclaimer: Business logic creeping into the UI is not really an architectural problem but a problem with developer discipline
  • 4. Let’s look at a “classic” architecture Persistence layer (JPA) Service layer (EJB) UI layer (Vaadin) Entities SQL database
  • 5. Problem 1 UI Operation Service 1 Service 2 Service 3 Actual transaction boundaries Logical transaction boundary
  • 6. Problem 2 UI CRUD Service+ Business logic in the user’s head and in the UI Service layer is only a frontend to the database
  • 7. Problem 3 UI 1 UI 2 UI 3 God Service
  • 8. Problem 4 Service A Service B New method ?
  • 10. Think about the transaction boundary ● Pay attention while coding and while reviewing others’ code ● The transaction boundary should IMO go between the UI and your backend ● Rules of thumb: ○ One UI operation, one backend call ○ One backend call, one transaction ○ One transaction, one thread ● Imagine your backend is running on a remote machine and you want to minimize the traffic
  • 11. Take care of your services ● Strive for highly cohesive services ● Avoid too general names like CustomerService ● Instead, opt for more specific names like CustomerOnboarding ● If you are adding a new service method and you find you could add it to more than one service, you should probably create a completely new one or refactor the existing ones
  • 12. Separate reading and writing ● Place your queries in separate components ● Create UI specific query components instead of adding more and more query methods to existing ones ● Allows for some neat optimizations and scaling
  • 13. Avoid CRUD ● CRUD UIs and services basically move the business logic into the head of the user ● Base your UIs and services on actual business processes and operations ● Exception: management UIs for reference and master data
  • 15. ● Think in terms of Commands and Queries ● A Command tells the system to perform a specific business operation ○ A command may return some result ○ A command either completes successfully or fails with an error ● A Query asks the system for specific data ○ A query always returns something ○ A query only fails because of external runtime errors such as network problems ● Commands and queries can be synchronous or asynchronous ● You can model each command and each query as a separate class Forget about services!
  • 16. The query/command class ● The name is always a verb in its imperative form ● The parameters are class attributes ● Use a generic parameter for the result, if any ● Try to make your class immutable ○ Not always possible, e.g. if you are binding a form directly to your command ● Validate the parameters inside your class ○ If you do this in the constructor, you cannot create a command or query with invalid parameters
  • 17. Examples <<command>> CreatePatient<Patient> firstName: string lastName: string gender: Gender birthDate: LocalDate <<query>> FindOrders<List<Order>> from: LocalDate to: LocalDate customer: Optional<Customer>
  • 18. Examples (code) public class CreatePatient implements Command<Patient> { final String firstName; final String lastName; final Gender gender; final LocalDate birthDate; public CreatePatient(String firstName, String lastname, Gender gender, LocalDate birthDate) { this.firstName = Objects.requireNonNull(firstName); … } }
  • 19. Examples (code) public class FindOrders implements Query<List<Order>> { final LocalDate from; final LocalDate to; final Optional<Customer> customer; public FindOrders(LocalDate from, LocalDate to) { … } public FindOrders(LocalDate from, LocalDate to, Customer customer) { … } }
  • 20. What about the implementation? ● Technically, queries and commands are implemented in the same way ● Each command/query has a handler ● The handler contains a single method that accepts the command/query as a single parameter and returns the result of the command/query ● Handlers are transactional ● Similar queries/commands can share a common base class ● Handlers can invoke other handlers
  • 21. Finding the correct handler ● A client will never invoke another handler directly ● Instead, commands/queries are passed to a broker or gateway ● The broker/gateway will look up the correct handler, invoke it and return the result
  • 22. Advantages ● An easy way of modeling the dynamics of the problem domain ● Forces you to think in terms of the domain while designing your UI ○ Since your UI should only be constructing and invoking commands/queries, the risk of business logic ending up there should be smaller (I hope) ● Your business logic consists of small, highly cohesive classes ● No more god classes ● Easy to distribute, e.g. by using a service bus ○ Command and queries could be serialized into JSON ○ Command and query handlers can be running anywhere ● Easy to run asynchronously ● You can use separate data sources for reading and writing ○ CQRS
  • 23. Master SlaveSlave Query Handler Query Handler Command Handler Broker UI
  • 24. Disadvantages ● More boilerplate code: for each operation, you have to write a command/query class and a handler class ● The client does not invoke the handler directly so if the handler is missing, it will not be detected until during runtime ● You have to write the command/query framework yourself ● You can still write too coarse or too fine grained commands
  • 25. Time for a code example!
  • 26. What about long-running transactions? ● Many commands participate in the same conversation ● If your container supports it, you can make your handlers conversation scoped ○ This makes it possible to store state in the handlers ● If you want your handlers to remain stateless, create a conversation object that is returned by and passed to every command handler ● The conversation object contains the state necessary to move the conversation forward
  • 27. Summary ● Discipline vs patterns ● Transaction boundary ● High cohesion ● Separate read and write ● Avoid CRUD ● Consider using commands and queries in business driven user interfaces