C l e a n A r c h i t e c t u r e
T r a v i s F r i s i n g e r
@ t m f r i s i n g e r
ABOUT
ME
- I have written software for over 25
years
- 17 of those professionally.
- Owner of StoneAge Technologies LLC
- Fractional CTO
- Trainer
- Speaker
- Using Clean Architecture for over 3
years.
- Started using it when there was
mainly only Uncle Bob’s blog post
about it.
- Used it on over 6 projects learning
lessons with each implementation.
- I maintain a few nuget packages that
simplify the boiler plate code of Clean
Architecture for .Net and .NetCore
Overview
C l e a n A r c h i t e c t u r e
MVC Migration TipsElements of Good Architecture The Architecture
How I evaluate an
architecture
Examination of the whole
and its parts
How to refactor your
existing architecture
Brief History
What came before
• Handle constant change while ensuring
maintainability of code base
• Easily facilitate teams working together
• Avoid ‘god’ classes
• Quality
Why do we need architecture?
C l e a n A r c h i t e c t u r e
• Testable
• Enables Technical Agility
• Independent of Frameworks
• Independent of UI
• Independent of Database
• Changes are easy to accommodate
• Easy to deploy
• Easy to implement
Elements of Good Architecture
C l e a n A r c h i t e c t u r e
- Layered
- MVC
- Microservices
Other Patterns
Brief History
C l e a n A r c h i t e c t u r e
Design Principles
- SOLID
- DRY
SOLID
C l e a n A r c h i t e c t u r e
• Single Responsibility
• A class should have only one reason to
change
• Open Closed
• Software entities (classes, modules, functions,
etc.) should be open for extension but closed
modification
• Liskov Substitution Principle
• Subtypes must be substitutable for their base
types
• Interface Segregation
• Clients should not be forced to depend on
methods they do not use
• Dependency Inversion
• A. High-level modules should not depend on
low-level modules. Both should depend on
abstractions.
• B. Abstractions should not depend on details.
Details should depend on abstractions.
DRY
C l e a n A r c h i t e c t u r e
• Don’t Repeat Yourself
• Every piece of knowledge must
have a single unambiguous,
authoritative representation in
the system.
• Often this principle is miss-
understood with developers
building abstractions for things
that look similar, but represent
different concepts. It is only
repeated if the code represents
the same concept. That is the
same sentence can be used to
describe what it represents.
Layered
C l e a n A r c h i t e c t u r e
UI
Business Logic
Persistence
• Components within the layered
architecture pattern are organized into
horizontal layers
• Each layer performing a specific role
within the application
• Request moves from layer to layer, it must
go through the layer right below it to get to
the next layer below that one.
Database
MVC
C l e a n A r c h i t e c t u r e
• Separates internal representation of
information from how the information is
presented and accepted from the user.
• Model – Manages data, logic and
business rules
• View – What the user sees
• Controller – Takes input and converts it to
operation for the model or view
Dependency
Graph Over Time
MVC + Repository
C l e a n A r c h i t e c t u r e
• MVC with the addition of decoupled data
storage
• Allows developer to apply S and D of
SOLID
• Increases testability of architecture
Microservices
C l e a n A r c h i t e c t u r e
• Quickly gaining ground in the industry as
a viable alternative to monolithic
applications and service-oriented
architectures.
• Each component of the microservices
architecture is deployed as a separate
unit or service component.
• Service components, which can vary in
granularity from a single module to a large
portion of the application
• All the components within the architecture
are fully decoupled from one other and
accessed through some sort of remote
access protocol
https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch04.html
Why Clean Architecture
C l e a n A r c h i t e c t u r e
“We should think about our application as a group of use cases that describe
the intent of the application and a group of plugins that give those use cases
access to the outside world.”
Uncle Bob
The Architecture
C l e a n A r c h i t e c t u r e
The Architecture
C l e a n A r c h i t e c t u r e
Presenters Repositories
Data Flow
C l e a n A r c h i t e c t u r e
Entry Point
Presenter
Use Cases
Entities
Repositories
Data Source
Dependency Rule
C l e a n A r c h i t e c t u r e
Entry Point
Presenter
Use Cases
Entities
Repositories
Data Source
Entry Point
Presenter
Composition Layer Domain Layer Data Layer
Use CasesEntities
Interfaces
Repositories
Network
Data Source
File System
Data Source
Use Case
Inputs
Dependency Inversion
C l e a n A r c h i t e c t u r e
Use Case Repository
Interface
Depends on Repository Interface Implements Interface
Injected into Use Case via IoC container
Data Models
C l e a n A r c h i t e c t u r e
Entities
Input Model
Mapper
Composition Layer Domain Layer Data Layer
Entities Repositories
Data Model
Mapper
Power of Presenters
C l e a n A r c h i t e c t u r e
Use Cases
Entities
Repositories
Data Source
Output
Presenter
Composition Layer Domain Layer
Use Case
Interface
Use Case depends on presenter
interface across boundary
Creates concrete presenter to
pass into use case depending on
needs to entry point
Use Case isVoid return.
Relies on the presenter to return data
Testing
C l e a n A r c h i t e c t u r e
Entry Point
Composition Layer
Use Case
Mock
Repository
Mock
Presenter
External
Mocks
Entities
(Http, File System)
Test Server
Testing
C l e a n A r c h i t e c t u r e
Use Case
Test
Presenter
Domain Layer
Services
Repository
Entity
Test Data
Services
I find often I pull services back
onto the entity where the data
sits.This means I need to test
them.
There may still be other 3rd
party services the entity needs
to do it’s job hence why they are
created as part of the testing
process.
Testing DB
Context
Make use ofTest
Data Builders to
populate this and
allow for re-use
across test.
Config
If making use of more then
one repository. Mock our the
non-critical repositories to
pass through in the test.
Testing
C l e a n A r c h i t e c t u r e
Repositories
Data
Layer
Repository
Services
Testing DB
Context
Config
- Well Structured
- Modular
- Very Testable
- Independent of Frameworks and Tools
- Maintainable
Benefits
- Boiler plate code
- Not suitable for all projects
- Multiple ways to implement
Issues
Issues and Benefits
Y o u r G r e a t S u b t i t l e H e r e
Tips for moving from standard MVC
to Clean Architecture
MVC
MIGRATION
- Use test to drive the process
- Create repositories for data operations
- Inject the repositories into your
controller
- Model Domain Entities
- Do not have controllers take Domain
Entities instead they should take an
Input TO and transform to Domain
entity
- Have repositories accept and return
Domain entity
- Migrate service logic onto the related
Domain Entity
- Create Use Cases to
- Use Repositories
- House remaining logic in Controller
- Coordinate Entities
- If need be create Composite Use
Cases to allow for re-use of common
business logic.
T h a n k Yo u
@ t m f r i s i n g e r
S o u r c e a n d P a c k a g e s
https://github.com/T-rav/Reference-CleanArchitecture-DotNet
(https://bit.ly/2FwXxsK)
https://www.nuget.org/profiles/T-rav
(https://bit.ly/2HDc5JJ)
References
C l e a n A r c h i t e c t u r e
• https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html
• https://github.com/mattia-battiston/clean-architecture-example
• https://proandroiddev.com/intro-to-app-architecture-922b392b21b2
• https://www.sitepoint.com/model-view-controller-mvc-architecture-rails/
• https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html
https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch04.html
• https://www.codingblocks.net/podcast/clean-architecture-make-your-architecture-scream/
• https://medium.freecodecamp.org/a-quick-introduction-to-clean-architecture-990c014448d2
• https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29

Clean architecture

  • 1.
    C l ea n A r c h i t e c t u r e T r a v i s F r i s i n g e r @ t m f r i s i n g e r
  • 2.
    ABOUT ME - I havewritten software for over 25 years - 17 of those professionally. - Owner of StoneAge Technologies LLC - Fractional CTO - Trainer - Speaker - Using Clean Architecture for over 3 years. - Started using it when there was mainly only Uncle Bob’s blog post about it. - Used it on over 6 projects learning lessons with each implementation. - I maintain a few nuget packages that simplify the boiler plate code of Clean Architecture for .Net and .NetCore
  • 3.
    Overview C l ea n A r c h i t e c t u r e MVC Migration TipsElements of Good Architecture The Architecture How I evaluate an architecture Examination of the whole and its parts How to refactor your existing architecture Brief History What came before
  • 4.
    • Handle constantchange while ensuring maintainability of code base • Easily facilitate teams working together • Avoid ‘god’ classes • Quality Why do we need architecture? C l e a n A r c h i t e c t u r e
  • 5.
    • Testable • EnablesTechnical Agility • Independent of Frameworks • Independent of UI • Independent of Database • Changes are easy to accommodate • Easy to deploy • Easy to implement Elements of Good Architecture C l e a n A r c h i t e c t u r e
  • 6.
    - Layered - MVC -Microservices Other Patterns Brief History C l e a n A r c h i t e c t u r e Design Principles - SOLID - DRY
  • 7.
    SOLID C l ea n A r c h i t e c t u r e • Single Responsibility • A class should have only one reason to change • Open Closed • Software entities (classes, modules, functions, etc.) should be open for extension but closed modification • Liskov Substitution Principle • Subtypes must be substitutable for their base types • Interface Segregation • Clients should not be forced to depend on methods they do not use • Dependency Inversion • A. High-level modules should not depend on low-level modules. Both should depend on abstractions. • B. Abstractions should not depend on details. Details should depend on abstractions.
  • 8.
    DRY C l ea n A r c h i t e c t u r e • Don’t Repeat Yourself • Every piece of knowledge must have a single unambiguous, authoritative representation in the system. • Often this principle is miss- understood with developers building abstractions for things that look similar, but represent different concepts. It is only repeated if the code represents the same concept. That is the same sentence can be used to describe what it represents.
  • 9.
    Layered C l ea n A r c h i t e c t u r e UI Business Logic Persistence • Components within the layered architecture pattern are organized into horizontal layers • Each layer performing a specific role within the application • Request moves from layer to layer, it must go through the layer right below it to get to the next layer below that one. Database
  • 10.
    MVC C l ea n A r c h i t e c t u r e • Separates internal representation of information from how the information is presented and accepted from the user. • Model – Manages data, logic and business rules • View – What the user sees • Controller – Takes input and converts it to operation for the model or view Dependency Graph Over Time
  • 11.
    MVC + Repository Cl e a n A r c h i t e c t u r e • MVC with the addition of decoupled data storage • Allows developer to apply S and D of SOLID • Increases testability of architecture
  • 12.
    Microservices C l ea n A r c h i t e c t u r e • Quickly gaining ground in the industry as a viable alternative to monolithic applications and service-oriented architectures. • Each component of the microservices architecture is deployed as a separate unit or service component. • Service components, which can vary in granularity from a single module to a large portion of the application • All the components within the architecture are fully decoupled from one other and accessed through some sort of remote access protocol https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch04.html
  • 13.
    Why Clean Architecture Cl e a n A r c h i t e c t u r e “We should think about our application as a group of use cases that describe the intent of the application and a group of plugins that give those use cases access to the outside world.” Uncle Bob
  • 14.
    The Architecture C le a n A r c h i t e c t u r e
  • 15.
    The Architecture C le a n A r c h i t e c t u r e Presenters Repositories
  • 16.
    Data Flow C le a n A r c h i t e c t u r e Entry Point Presenter Use Cases Entities Repositories Data Source
  • 17.
    Dependency Rule C le a n A r c h i t e c t u r e Entry Point Presenter Use Cases Entities Repositories Data Source Entry Point Presenter Composition Layer Domain Layer Data Layer Use CasesEntities Interfaces Repositories Network Data Source File System Data Source Use Case Inputs
  • 18.
    Dependency Inversion C le a n A r c h i t e c t u r e Use Case Repository Interface Depends on Repository Interface Implements Interface Injected into Use Case via IoC container
  • 19.
    Data Models C le a n A r c h i t e c t u r e Entities Input Model Mapper Composition Layer Domain Layer Data Layer Entities Repositories Data Model Mapper
  • 20.
    Power of Presenters Cl e a n A r c h i t e c t u r e Use Cases Entities Repositories Data Source Output Presenter Composition Layer Domain Layer Use Case Interface Use Case depends on presenter interface across boundary Creates concrete presenter to pass into use case depending on needs to entry point Use Case isVoid return. Relies on the presenter to return data
  • 21.
    Testing C l ea n A r c h i t e c t u r e Entry Point Composition Layer Use Case Mock Repository Mock Presenter External Mocks Entities (Http, File System) Test Server
  • 22.
    Testing C l ea n A r c h i t e c t u r e Use Case Test Presenter Domain Layer Services Repository Entity Test Data Services I find often I pull services back onto the entity where the data sits.This means I need to test them. There may still be other 3rd party services the entity needs to do it’s job hence why they are created as part of the testing process. Testing DB Context Make use ofTest Data Builders to populate this and allow for re-use across test. Config If making use of more then one repository. Mock our the non-critical repositories to pass through in the test.
  • 23.
    Testing C l ea n A r c h i t e c t u r e Repositories Data Layer Repository Services Testing DB Context Config
  • 24.
    - Well Structured -Modular - Very Testable - Independent of Frameworks and Tools - Maintainable Benefits - Boiler plate code - Not suitable for all projects - Multiple ways to implement Issues Issues and Benefits Y o u r G r e a t S u b t i t l e H e r e
  • 25.
    Tips for movingfrom standard MVC to Clean Architecture MVC MIGRATION - Use test to drive the process - Create repositories for data operations - Inject the repositories into your controller - Model Domain Entities - Do not have controllers take Domain Entities instead they should take an Input TO and transform to Domain entity - Have repositories accept and return Domain entity - Migrate service logic onto the related Domain Entity - Create Use Cases to - Use Repositories - House remaining logic in Controller - Coordinate Entities - If need be create Composite Use Cases to allow for re-use of common business logic.
  • 26.
    T h an k Yo u @ t m f r i s i n g e r
  • 27.
    S o ur c e a n d P a c k a g e s https://github.com/T-rav/Reference-CleanArchitecture-DotNet (https://bit.ly/2FwXxsK) https://www.nuget.org/profiles/T-rav (https://bit.ly/2HDc5JJ)
  • 28.
    References C l ea n A r c h i t e c t u r e • https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html • https://github.com/mattia-battiston/clean-architecture-example • https://proandroiddev.com/intro-to-app-architecture-922b392b21b2 • https://www.sitepoint.com/model-view-controller-mvc-architecture-rails/ • https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch01.html https://www.oreilly.com/library/view/software-architecture-patterns/9781491971437/ch04.html • https://www.codingblocks.net/podcast/clean-architecture-make-your-architecture-scream/ • https://medium.freecodecamp.org/a-quick-introduction-to-clean-architecture-990c014448d2 • https://proandroiddev.com/clean-architecture-data-flow-dependency-rule-615ffdd79e29

Editor's Notes

  • #14 Clean architecture helps us solve, or at least mitigate, these common problems with architecture: Decisions are taken too early, often at the beginning of a project, when we know the least about the problem that we have to solve It's hard to change, so when we discover new requirements we have to decide if we want to hack them in or go through an expensive and painful re-design. We all know which one usually wins. The best architectures are the ones that allow us to defer commitment to a particular solution and let us change our mind It's centered around frameworks. Frameworks are tools to be used, not architectures to be conformed to. Frameworks often require commitments from you, but they don’t commit to you. They can evolve in different directions, and then you’ll be stuck following their rules and quirks It's centered around the database. We often think about the database first, and then create a CRUD system around it. We end up using the database objects everywhere and treat everything in terms of tables, rows and columns We focus on technical aspects and when asked about our architecture we say things like “it’s servlets running in tomcat with an oracle db using spring” It's hard to find things which makes every change longer and more painful Business logic is spread everywhere, scattered across many layers, so when checking how something works our only option is to debug the whole codebase. Even worse, often it's duplicated in multiple places Forces/Encourages slow, heavy tests. Often our only choice for tests is to go through the GUI, either because the GUI has a lot of logic, or because the architecture doesn't allow us to do otherwise. This makes tests slow to run, heavy and brittle. It results in people not running them and the build beind broken often Infrequent deploys because it's hard to make changes without breaking existing functionalities. People resort to long-lived feature branches that only get integrated at the end and result in big releases, rather than small incremental ones Clean architecture gives us all these benefits: Effective testing strategy that follows the testing pyramid and gives us a fast and reliable build Frameworks are isolated in individual modules so that when (not if) we change our mind we only have to change one place, with the rest of the app not even knowing about it Independent from Database, which is treated just like any other data provider. Our app has real use cases rather than being a CRUD system Screaming architecture a.k.a. it screams its intended usage. When you look at the package structure you get a feel for what the application does rather than seeing technical details All business logic is in a use case so it's easy to find and it's not duplicated anywhere else Hard to do the wrong thing because modules enforce compilation dependencies. If you try to use something that you're not meant to, the app doesn't compile We're always ready to deploy by leaving the wiring up of the object for last or by using feature flags, so we get all the benefits of continuous integration (no need for feature branches) Swarming on stories so that different pairs can easily work on the same story at the same time to complete it quicker Good monolith with clear use cases that you can split in microservices later one, once you've learnt more about them Of course, it comes at a cost: Perceived duplication of code. Entities might be represented differently when used in business logic, when dealing with the database and when presenting them in a json format. You might feel like you're duplicating code, but you're actually favouring decoupling over DRY You need interesting business logic to "justify" the structure. If all you do in your use case is a one-line method to read or save from a database, then maybe you can get away with something simpler