Simplified concept of Clean Software Architecture adjusted for Backend applications

Using clear and known rules during software development process is very important. It will help to achieve good software quality. During development of software there is need to cooperate by many persons in team. Keeping the same structure by all members will help to avoid misunderstandings. Good structure of code and logical separation of its layers will give possibility to extend it in more simple way at future changes. Using good architecture just make simple to understand it, not only by programmer.

zizome / Pixabay

Design and Code patterns

What patterns were used to define concept of clean architecture project?

  • CQRS (Command Query Responsibility Segregation)
  • Event Sourcing
  • Domain Driven Design
  •  Access to Datastore in NoSQL concept
  • Separate Models

By choosing ready to use patterns or part of their solutions it’s much easier to achieve understanding of architecture that may fit to expected needs. Most important is to choose for a project only this what is really needed. There is no need to use anything more, just for a future use. For sure you will never need it. Keeping architecture structure as clear as possible is the key to success. Very important thing is to write down rules at the beginning of project and using them until the very end. Changes during development will make many misunderstandings.


For start let’s just use package based separation of Commands and Queries. There is no need to go further with this pattern at the very beginning. Commands and Queries Responsibility Separation in definition means not only logical separation but also physical separation. To achieve possibility of physical separation at deployment level it’s good to start only with logical one. In case of need the physical one is always possible to implement, when structure is already in code. How it will work? Application Interface like REST layer will generate a Command or Query, pass it to Delivery and then chosen implementation of dispatching will execute related Use Case in the Core. Suggestion is to use always at minimum described package based separation of Commands and Queries or to use naming based separation in classes. Example: DoSomethingCommand, GetSomethingQuery.

Event Sourcing

Can use complete solution or just a part of it. For simplicity there is not always need to use complex Event Sourcing pattern. It may be that well described Use Cases already fulfill need of description what has happened in system. In more complicated systems where one Use Case is making more changes, then producing a list of events by Use Case and then apply them to State is a need. Most important is to understand that Event Sourcing has a relation to chosen already Commands and Queries separation, as goal to descriptive system changes is already presented at some level. It’s a free choice of how much from Event Sourcing will be implemented and defined in system. In many cases, there is good enough to stay only with solution that Use Cases related to Commands will produce Events that are later translated to changes in data. This will also be a way to further patterns related with Transactional Logging, Audit Logging and Session Logging. Even choosing simplification to create Events just for logging purpose is also the solution that may fit to system requirements.

What do we want to achieve?

  • Single responsibility in a small domain
  • Clear business needs and implementation rules
  • Separation of different models
  • Separation of business logic from it’s infrastructure implementation
  • Application layer independency from core business
  • Simple way to extend functionality and scalability

Single responsibility in a small domain concept for a system

  • Domain Driven Design
  • Micro-services
  • Multi-modules architecture

(i) Allow to transfer micro-service into module and back

(ii) Infrastructure component may use another module or micro-service

  1. Threat each module or micro-service as an independent application
  2. Fit concept to your needs and not your need to concept
  3. Define main flow of application and use cases to achieve that
  4. Define processes to achieve use cases as business
  5. Separate application’s model from business’ model and from infrastructure’s

Example of Main Flow with list of Use Cases

Defining list of business Use Cases


  • Add new import source
  • Delete an import source
  • List of all import sources


  • Trigger of Main Process
  • Check currently running process status


  • See a list of all reports
  • See one report

Defining of a context with micro-serivces, modules, components

  • Microservices may do some generic tasks
  • Modules in application can be treat as an external application
  • Components are smaller than modules as a part of infrastructure

Application’s architecture as implementation rule

General list of structured packages in project. Each one have different role.

  • APPLICATION (Interfaces like REST, JAVA)
  • BOUNDARY (Inbound, Outbound, Commands) as application model
  • DELIVERY (Execution, Presentation)
  • CORE (Business, Use Cases)
  • DATA (business model)
  • INFRASTRUCTURE (http clients, database with it’s model, implementations)

Application’s architecture in flow of usage

CQRS not only for systems, but also for internal architecture

Application layer initialize Core with Infrastructure components

It is important that CORE will not have real implementations for clients, connections, etc.

Application executes Commands and Queries in Core using Delivery

Connection to application takes place using Interfaces. For example http client will connect to Application’s API at Interfaces layer and then application is executing generated Command or Query. Such a Command or Query is executed as a Use Case from Core layer using the Delivery implementations.

Delivery can be replaced very quickly by different implementations. Can be used Akka, Local Executor, Async Execution, Network Execution or any other.

Delivery execute Commands and render Responses

  • Local execution
  • Actor based execution
  • Network execution
  • Java execution / presentation system
  • Http based presenting system
  • Synchronous or Async depend on system needs

Core is a clear business

  • List of Use Cases
  • Main Flow as Process
  • Shared Processes between many Use Cases
  • Business logic that operate on Data using Components (java interfaces)
  • Using Boundary for income and outcome of business
  • May produce a list of events as outcome of State changes

Infrastructure get its work to be done

  • Implementation of Components defined in Core
  • Easy way to switch between different types of implementation
  • Using Data as income and outcome of Components
  • Sends and stores Data in own format depend on library or framework
  • Multi-model implementations transformed to Business Data
  • Separation of implementation from any business logic


  1. Testability on each layer (API, Business, Frameworks)
  2. Performance scalability
  3. Separation of Api model from Data model and Infrastructure model
  4. Easy way to change implementation of components (modularity)
  5. Track events in System and State
  6. Clear rules of implementation in code for any Team Member


(soon) See here later for next posts 🙂