Back to Home

Domain vs Application Logic

Domain vs Application Logic in Domain-Driven Design

Problem vs Solution Space

When defining a business problem and planning its solution, keep the two conversations separate so that the problem is understood in as much detail as possible first. Business logic is part of the Solution Space so should be discussed only after thoroughly understanding the problem.

  • The Problem Space identifies the purpose, the "why".
  • The Solution Space is the "how".

Common DDD terminology falls into each category:

Problem Space

  • Domain
  • Problem Domain
  • Core Domain
  • Subdomain

Solution Space

  • Business Logic
  • Business Rules
  • Domain Logic
  • Bounded Context

The terms Domain, Problem Domain, Core Domain are synonymous, as are Business Logic, Business Rules, and Domain Logic; these terms are used interchangeably.

After understanding the problem space, we can dig in to the rules that solve the business problem and encode this domain knowledge in explicit logic.

This Business Logic solves the problem at hand but does not address implementation details such as database technology, API definitions, web frameworks, etc. Our business logic should encode what rules are needed to solve the problem with language everyone can understand.

Keep Things Simple

Business Logic

Business logic should be created in collaboration with business experts. Our primary purpose as software engineers is to convert that logic into an implementation that can be executed.

So, let's keep things simple and separate our domain model from the application details. If we capture the business logic in an isolated area of our code, write the code using terms anyone can understand from the problem domain, and keep all application details out of this area, it is much easier to understand the purpose of the solution and update the business rules when needed.

How do we know what the domain logic is? Ask whether the code makes decisions that have business meaning. Any business-critical decision should be done in the domain logic; everything else is wiring.

Application Logic

This wiring code is the Application Logic. This layer sadly represents the bulk of complexity and effort in many systems, despite the fact that it is simply necessary and has minimal impact on your business's competitive edge: a topic for another day.

The application logic orchestrates executing the business logic and all of the infrastructure details like persistence, UI, external system communication, etc. The application layer hosts an environment for executing domain logic; it collects and transforms external input into forms that the business logic uses to make decisions.

Usually the application layer communicates using primitive data types and converts them into domain-specific data types for clarity.

Application Architecture

In order for the application layer to do its job of orchestration, it is helpful to further separate implementation details of specific technologies into adapters. Uncle Bob's Clean Architecture is a wonderful approach to this.

Infrastructure

Infrastructure adapter implementations could include management of the following application concerns, for example:

  • Data persistence (e.g. in-memory, MySQL, file system, DynamoDB)
  • User notifications (e.g. email, SMS)
  • Web API (e.g. REST, GraphQL, web socket)
  • UI frameworks

Dependency Inversion

Each infrastructure adapter can implement an interface that is defined in the application layer. During startup the implementation can be instantiated and dependency injected into the application layer. This isolates the application layer from infrastructure changes, which has the massive benefit of allowing an effort like swapping a database technology to not require a full application rewrite; only the infrastructure adapter needs to be re-implemented against the same interface.

This leads to a dependency flow where the detailed infrastructure implementations depend on the application layer, and the application layer depends on the domain logic. Our domain logic is kept pristine without any external dependencies.

  • Infrastructure Adapter (e.g. DB, REST API, external service communication) depends on ->
  • Application Logic (orchestrates the flow of requests and executes business logic) depends on ->
  • Business Logic (makes business-critical decisions) depends on nothing

References

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

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

Read More

Printable cheat sheets to help remember some of Uncle Bob's valuable contributions to the industry

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