Back to Home

Clean Architecture and SOLID Cheat Sheets

Good architectures allow major architectural decisions to be deferred. The job of an architect is not to make decisions, the job of an architect is to defer decisions as long as possible to allow the program to be built in the absence of decisions, so that decisions can be made later with the most possible information.

— Robert C Martin, The Principles of Clean Architecture, Norwich UK, 2015

Sources from Uncle Bob

SOLID Design Principles

SRP: Single Responsibility Principle

Does not necessarily mean that a module should do just one thing, but that a module should have only one reason to change.

OCP: Open-Closed Principle

A module's behavior can be modified without modifying the core code; class inheritance and composition. For example: to swap out a DB implementation, the business logic should not need to be modified.

LSP: Liskov Substitution Principle

Concrete implementations must adhere to the expected interface contracts.

ISP: Interface Segregation Principle

Keep interfaces small!

DIP: Dependency Inversion Principle

  • Interface abstractions are more stable (change less frequently) than concrete implementations
  • Use the factory pattern to keep concrete implementations out of business logic
  • Use a small number of concrete "main" components, where all DIP violations are gathered

Architecture

The goal of software architecture is to minimize the human resources required to build and maintain the required system.

— Robert C Martin, Clean Architecture: A Craftsman's Guide to Software Structure and Design

Two words "soft" and "ware" mean an easily changeable product.

The "policy" (i.e. business logic) is essential; the "details" (e.g. I/O, frameworks, protocols, etc) are irrelevant to it.

Defer architectural decisions as long as you can, so you have the most information possible. For example, wait to choose a DB technology and web framework until the core business app is built.

A good architecture maximizes the number of decisions not made. And you achieve that by using a plugin model.

— Robert C Martin, The Principles of Clean Architecture, Norwich UK, 2015

Dependency Inversion

  • UI, frameworks, persistence/database, etc depend on the business logic (not the other way around).
  • Only inject some strategies and factories, keep it limited.
  • Do not inject your business logic directly into the app. Instead, inject into a plugin abstraction, then the plugin distributes objects. This is so business logic and its tests do not need to know about injection framework.
  • Do not couple your app to the framework, keep it at arms length.

Business Logic at a Glance: Source Code Structure

Someone new looking at the code should primarily see the business logic; the technical implementation details should be hidden away.

  • Primary focus of structure should be to describe the business domain
  • Implementation details should be low-level and should take a back-seat to domain logic in source code

Printable Cheat Sheets

SOLID Design Principles

Clean Architecture Black & White

Clean Architecture Diagram

Clean Architecture Diagram with Text

Related Posts

The essential design concepts I use when developing an evolvable, distributed system.

Read More

How can we continuously integrate small changes while practicing acceptance test-driven development?

Read More

TDD and Testing Behavior

January 24, 2024

The importance of testing behavior when using test-driven development

Read More

When is it appropriate to use centralized orchestration versus event-driven choreography?

Read More

When defining a business problem and planning its solution, keep the two conversations separate...

Read More

Modern message brokers provide many important benefits to a distributed system...

Read More

Why Terraform?

December 25, 2019

Terraform leads the way in the infrastructure-as-code world...

Read More

I was looking for a quick and easy way to put together a personal static site and...

Read More

A few weeks ago, I decided to try Svelte's Sapper framework to handle the front-end of a simple app...

Read More

After years of consulting, I find myself continually coming back to three basic principles of system design...

Read More

In this fifth and final part of the Go middleware tutorial series, we'll use what we've learned to create a more structured API example...

Read More

Go Middleware - Part 4

February 24, 2019

In this fourth part of the Go middleware tutorial series, we'll discuss passing custom state along the request chain.

Read More

Go Middleware - Part 3

February 15, 2019

In this third part of the Go middleware tutorial series, we'll quickly look at a common variant on the recursive middleware implementation from part 2.

Read More

Go Middleware - Part 2

February 9, 2019

In this second part of the Go middleware tutorial series, we'll cover a recursive approach that provides a couple benefits beyond the simple loop chain example from part 1.

Read More

Go Middleware - Part 1

February 6, 2019

This is the first in a series of simple tutorials explaining the usage of HTTP middleware in Go.

Read More

How do we manage the architectural complexity that inevitably arises from using cloud services?

Read More

This Old Blog

January 20, 2019

I've decided to resurrect this old blog to publish some nuggets about software architecture and development, and perhaps...

Read More

Drupal 6 Theme Info Error

September 14, 2011

Recently one of my client sites had an issue where the custom theme info was corrupted...

Read More

Here's a slight modification to the handy Google Bookmarks Bookmarklet...

Read More

While building a Drupal site for one of my clients, I was having a heck of a time integrating...

Read More