That Conference 2016 – Clean Architecture: Patterns, Practices, and Principles

That Conference 2016, Kalahari Resort, Lake Delton, WI
Clean Architecture: Patterns, Practices, and Principles
Matthew Renze – @matthewrenze

Day 3, 10 Aug 2016

Disclaimer: This post contains my own thoughts and notes based on attending That Conference 2016 presentations. Some content maps directly to what was originally presented. Other content is paraphrased or represents my own thoughts and opinions and should not be construed as reflecting the opinion of the speakers.

Executive Summary

  • A whirlwind overview of domain-centric architecture and discussion of its merits
  • Overview of CQRS architectures (Command and Query Responsibility Segregation)
  • Brief mention of microservices architectures

Story – Tale of two architecures

  • John/Jane, same expertise
  • Hire them to design two buildings, same purpose
  • John
    • Superstar, creates the architecture, hands off to builder
  • Jane
    • Starts by talking to inhabitants and crews
    • Then involved during construction, helping implement
    • Tweaks plan as necessary
  • Captures essence of difference between clean architecture and traditional

About Me

  • Consultant
  • Pluralsight
  • Msft MVP

Focus

  • Enterprise architecture
  • Line-of-business applications
  • Modern equivalent of 3-layer
  • Will talk about 6 key ideas

What is software architecture?

  • High-level – higher level than the code
  • Structure
  • Layers – vertical partitions of system
  • Components – sub-divisions of layers, or horizontal
  • Relationships – how wired

Levels of architectural abstraction

  • System
  • Sub-systems
  • Layers
  • Components
  • Classes
  • Data and methods

Messy vs. Clean Architecture

  • Bad – like spaghetti
  • Good – lasagna
    • Nice layers

What is Bad Architecture?

  • Complex – accidental
  • Inconsistent
  • Incoherent – things don’t fit
  • Rigid – not adaptible
  • Brittle
  • Untestable
  • Unmaintainable

Clean Architecture

  • Simple
  • Understandable – easy to reason about
  • Flexible
  • Emergent
  • Testable
  • Maintainable – easier to maintain over lifetime

Clean architecture

  • Architecture that is designed for inhabitants of the architecture
    • Not for architect
    • Or for machine
  • Start designing architecture for inhabitants
    • This is the primary concern
    • Everything else is secondary

Why is clean architecture important?

  • Cost/benefit
  • Minimize cost to maintain
    • Good to optimize for maintainability
    • Since most cost is spent during maintenance
  • Maximize business value

Decisions

  • Context is king
    • Answer always depends on context
  • All decisions are a tradeoff
  • Use your best judgment

Domain-Centric Architecture

  • Heliocentric was more elegant model of the solar system

Classic 3-layer architecture

  • Database at central, then data access, business logic

Domain-centric

  • Domain at center
  • Application around that
  • Then Application
  • Database hung off the side

Uncle Bob

  • Most important thing is that the architecture is usable

Essential vs. Detail (e.g. for house)

  • Space is essential
  • Usability is essential
  • Building material is a detail
  • Ornamentation is a detail

Essential vs. Detail (Clean architecture)

  • Domain is essential
    • Domain: series of object models at center
    • Mirrors the mental models of the domain
  • Use cases are essential
    • And users
  • Presentation is a detail
  • Persistence is a detail
    • Can store in relational DB, NoSql, doc DB, etc.

Back to domain-centric diagram

  • What is essential is at the center of the diagram
  • Domain essential
    • At center
    • Everything points towards the domain

Hexagonal architecture

  • Application layer (domain) at center
  • Adapting to presentation
  • Adapting to do input
  • Adapting to persistence

Onion Architecture

  • Domain Model at center
  • Services
  • UI at outer

The Clean Architecture (Uncle Bob’s)

  • Entities at center
  • Use Cases
  • Controllers
  • Outside: Devices, Web, UI, External Interfaces

It’s all the same thing

  • All three of these are fundamentally the same
  • Domain at the center

Why use domain-centric architecture?

  • Pros
    • Focus on essential
    • Less coupling to details
    • Necessary for DDD
  • Cons
    • Change is difficult
    • Requires extra thought
    • Initial higher cost

Application Layer

  • Might embed use cases as high-level logic

What are layers?

  • Levels of abstraction
  • Single-Responsibility
  • Developer roles/skills
  • Multiple implementations

Classic 3-layer architecture

  • Database at bottom
  • Data Access
  • Business Logic
  • UI
  • Users
  • Top layers dependent on layer below it

Modern 4-layer architecture

  • Presentation at top
  • Application below that
  • Domain layer
    • Only domain logic
  • Persistence below application
    • Access to DB
  • Infrastructure below application
    • Access to OS

Application layer

  • Implements use cases
  • High-level application logic
  • Knows about domain layer but not persistence or infrastructure
  • No knowledge of upper layers

Layer Dependencies

  • Dependency inversion
  • Inversion of control
    • Details depend on abstractions
  • Independent deployability
  • Flexibility and maintainability
  • Flow of control
    • Presentation calls Application
    • Persistance calls Application

Example

  • Presentation layer w/controller
  • Application
    • Command dep on IDatabaseContext, IInventoryClient
    • Application–what the users are doing with the system
      • E.g. ICreateSalesCommand
  • Dep on Sale in Domain
    • Domain–objects in system
      • e.g. Sale object
  • Interface in cross-cutting concerns

Why use an application layer?

  • Pros
    • Focus is on use cases
    • Easy to understand
    • Follows DIP – Dependency Inversion Principle
  • Cons
    • Additional cost
    • Requires extra thought
    • What is application logic vs. domain logic ?
    • IoC is counter-intuitive

Commands and Queries

  • Keep separated
  • Command
    • Do something
    • Modifies state
    • Should not return value
  • Queries
    • Answer question
    • Do not modify state
    • Always returns value
  • Why?
    • Avoid side-effects
  • Sometimes odd, exceptions
    • E.g. create record, return it

CQRS Architectures

  • Application layer, separate into two parts
  • Left
    • Queries
    • Data Access
  • Right
    • Commands
    • Domain
    • Persistence
  • Database at bottom
  • Data flow
    • Down through commands
    • Up through queries
  • CQRS is domain architecture done in sensible way

CQRS Type 1 – Single Database

  • Single database, typically NoSQL
  • Persistence layer might be something like EF
  • Queries – stored proc, linq to sql

CQRS Type 2 – Read/Write Databases

  • Command stack leads to Write Database
    • 3NF
  • Read database
    • 1NF, optimized for reads
  • Use “eventually consistent” model to push data across from write to read
  • Orders of magnitude performance improvement over single database
    • Because we mostly do reads, not writes

CQRS Type 3 – Event Sourcing

  • Command stack leads to Event Store
  • Read database under query stack
  • Replay events to get current state of entity (from deltas)
  • State modifications pushed over to Read Database

Type 3 points

  • Complete audit trail
  • Point-in-time reconstruction
  • Replay events
  • Rebuild production database
    • Just by replaying events
  • Only worth doing if you need these features

Why use CQRS?

  • Pros
    • More efficient design
    • Simpler within each stack
      • At expense of inconsistency across stacks
    • Optimized performance
      • Of each side
  • Cons
    • Inconsistent across stacks
      • More complexity
    • Type 2 is more complex
      • Adds consistency model
    • Type 3 might be overkill
      • If you don’t get business value from these features

Functional organization

  • Screaming architecture
    • Architecture should scream the intent of the system
  • Organize architecture around use cases
  • Uncle Bob

Building metaphor

  • House, typical
    • Intent – residential
    • Rooms embody uses–bedroom, kitchen, living room
    • Architecture shows use
  • Look at list of components, rather than architectural diagram
    • Can’t infer intent

Software intent

  • Could organize folders by components (models, views, controllers)
  • Or organize by things
    • Customers, products, vendors

This vs. that

  • Traditional
    • Content, Controllers, Models, Scripts
  • Functional
    • Customer
    • Product

So what?

  • Functional cohesion is more efficient
    • Because it better models how we think about the software

Why use functional organization

  • Pros
    • Spatial locality
    • Easy to navigate
    • Avoid vendor lock-in
  • Cons
    • Lose framework conventions
    • Lose automatic scaffolding
    • Categorical is easier at first

Microservices

Components

  • Horizontal – UI, business, data access
  • Vertical – Sales, Support, Inventory
  • UI presents all vertical pieces as single unified UI

Problem Domain

  • Sales and Support

Single domain model

  • Traditionally, create single domain model
  • E.g. Product on both sides, so we have single Product entity
  • Employee – sales or service
  • Problem
    • Becomes exponentially more difficult

Bounded contexts

  • Sales and support as boundaries
  • Some entities in just Sales
    • Some in Support
    • Some in overlap
  • Then pull apart and have separate models for each context

Microservice architectures

  • Subdivide system
    • Communicate with each other via lightweight mechanisms
  • Bounded contexts
    • Can have one agile team per bounded context
    • Only have to know about one bounded context
  • Small teams
  • Qualities
    • Independent
    • Similar to SOA
    • Independently deploy and scale each microservice
  • Size of microservices
    • Ongoing debate
    • Bounding context maps to microservice
    • So persistence model matches context matches service
    • “Goldilocks” point

Why use microservices?

  • Pros
    • Less cost for large domains
    • Smaller teams
    • Independence
      • Don’t need to know what other teams are doing
  • Cons
    • Only for large domains
      • Overkill for small domains
      • Lot of overhead cost for microservice
    • Higher up-front cost
      • Fault tolerance, latency, load balancing
      • Might start with single system, split when you have multiple bounded contexts
      • – Distributed system costs

Code Demo

  • Solution architecture for simple web site
  • ASP.NET MVC 5
  • Top-level folders
    • Application, Common, Domain, Infrastruccture, Peristence, Presentation
  • Presentation, Sales folder
    • sub-folders Models, Services, views
  • Application layer
    • Sales | Commands, Queries
    • Under Commands, folder for each command
  • Domain layer
    • Fairly thin object model
    • But a small amount of business logic in the objects

Where to go next

  • Patterns of Enterprise Application Architecture – Fowler
  • Bliki has updated stuff
  • Clean Code – Uncle Bob
    • cleancoders.com
    • Great
  • Domain-Driven Design – Evans
    • For complex domains
  • Greg Young, Udi Dahan
    • CQRS event sourcing
  • matthewrenze.com
    • Pluralsight courses as well

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s