Last updated: May 11, 2026

Solution Architecture

Solution architecture is all about deriving architectural direction and vision to the organisation, translating areas of development or domains into well-organised self-directed teams, providing guidance on how to develop cross-functionally.

Note from Author

Bring in Team Topologies

Organisation

If the organisation has many departments or teams that develop software, or is part of the process in developing it, it is important that these organize themselves and the processes they follow in an efficient manner.

  • Stakeholders
  • Systems Design
  • Requirement Management
  • Project Management

Common Workflow & Conventions

Identifying commonalities across departments and teams, and streamlining the workflow and conventions employed allow for efficient cross-domain work and alleviate double-work. If are different conventions or indeed none or few, establishing common conventions and ways of working is paramount to ensure a smooth and fast development flow.

Note from Author

This section may need to be moved to a more appropriate place of introduction

Guidelines

  • Style guide — use an existing one, don't invent your own. Make amendments to the existing one if absolutely necessary.

Code Management

Note from Author

Describe this in more detail

In order to illustrate how to manage your code we will have to use a specific language for the examples, but the concepts will carry over to any project. The core of the concept is that of modularity. For the examples I will be using C++.

File Structure
doc
ARCHITECTURE.md High-level description of the architecture
modules/
module_0 Self-contained unit of the system
doc Documentation of the module (UML diagrams, markdown, etc.)
inc Public API for the module
src Implementation of the module
mock Mocks of the module, for use in dependent module's tests
test Contain tests of this module's functionality
unit Unit-tests that mock any of this module's dependencies
target Target tests that tests the behaviour of the module deployed onto a target
README.md A high-level description of the module and how to use it
module_1
module_2
lib Contains external dependencies - usually weak references like git submodules
sdk vX.Y.Z External libraries like an SDK
pytest vX.Y.Z Frameworks for target-testing (PyTest is just an example)
googletest vX.Y.Z Frameworks for unit-testing (Google Test is just an example)
scripts A collection of scripts useful to the developer
cmake CMake-specific scripts
module.cmake
tools Contains tools used in the project
CHANGELOG.md Used to track changes across releases and generate release notes.
README.md Used to give guidance on how to build, deploy and release.

Pipeline Management

Note from Author

Describe this

Branch & Release Strategy

Note from Author

Describe this

Semantic Versioning

Any and all projects should have a well-defined way of signifying release versions. For this I recommend following the format specified by Semantic Versioning.

Change Log

It is important to establish a well-defined way of tracking changes in projects. For this I recommend following the guidance of Keep A Changelog.

Conventional Commits

Note from Author

Describe how conventional commits are formatted their intended meaning

Read about it in detail at Conventional Commits

Semantic Releases

Bringing all of these together to form a fully automated solution for version management, semantic release alleviates a lot of manual work and streamlines the process.

Note from Author

Describe how semantic releases work

Read about it in detail at Semantic Release

Identify Business Needs

Note from Author

Describe identifying business needs
  • As a business I want to ...

Identify Domains

The business needs map into domains which the organisation will distribute work between.

A domain is to provide the functionality of the domain and only that. As such, for software-related domains, we will consider the product of the domain to deliver a platform. More specifically, a software platform.

Dependency Inversion

Note from Author

This is a lead in to understanding how the domain can use hardware-specific implementations without depending explicitly on it.

The principle is expressed in two statements

A: High-level modules should not import anything from low-level modules. Both should depend on abstractions (e.g., interfaces).

B: Abstractions should not depend on details. Details (concrete implementations) should depend on abstractions.

Read more about it at Dependency Inversion

Target Integration

A target integration is in this context refers to the act of integrating a domain into a particular target. A target is also a rather abstract term, but appropriately so as it may be anything that makes the domain functionality available on the target which runs it. This could be a specific OS, like Windows or MacOS, or mobile targets like Android and iOS. Or, more exotically, it could be specific hardware integrations for embedded systems.

Put in another way, an integration is merely adapting the domain to a specific system we want to use it on. And there's a keyword ‐ use. We therefore have the relationship shown below. More specifically, since we want these development areas to be able to work independently of each other the integration shall use a specific version of the domain.

Loading diagram...

This indirection on the integration means we can implement a domain toward a specific target. That is, we can use the domains on different target platforms.

Domain Repository
/my_domain
/modules
/filter abstract filter - provides the interface for integration
/butterworth_filter butterworth filter - uses the filter interface
/fast_fourier_transform

The domain supplies domain-level features. That is, features that solely are defined and implemented by the domain itself ‐ not project-level features. Consider for instance the domain of signal processing, which might provide features like filters or algorithms.

Integration Repository
my_integration
/modules implementations for the modules of the domain
/filter implementation of the abstract filter provided by the domain
/lib
/my_domainv1.2.3 git submodule pointing to v1.2.3 of the domain
/modules

Projects & Variants

A variant is a concrete build of project.

Loading diagram...

This gives us the following folder structure.

Project Repository
my_project
/apps Contains variants we would like to build for this project
/variant_a Could be the consumer variant
/variant_b Could be a test-specific variant
/variant_c Could be a custom build for different department
/modules
/lib
/my_integrationv1.2.3 git submodule pointing to version 2.6.1 of the integration
/modules
/lib
/my_domainv1.2.3 git submodule pointing to version 3.2.1 of the domain

With these two levels of indirection we have a well-defined relationship between domains, their integrations into target-specific implementations, as well as a project-specific configurations.

Composable Architecture

Of course, different products make use of multiple domain-level features in order to provide a user-level feature. Hence, a product repository will usually make use of multiple integrations of domains.

Loading diagram...
Project Repository
my_project
/modules
/lib
/my_integration_av2.6.1 git submodule pointing to version 2.6.1 of the integration
/modules
/lib
/my_domain_av3.3.4 git submodule pointing to version 3.3.4 of the domain
/my_integration_bv1.2.6 git submodule pointing to version 1.2.6 of the integration
/modules
/lib
/my_domain_bv2.1.0 git submodule pointing to version 2.1.0 of the domain
/my_integration_cv3.1.8 git submodule pointing to version 3.1.8 of the integration
/modules
/lib
/my_domain_cv1.1.4 git submodule pointing to version 1.1.4 of the domain

Building Bridges

Now a natural question arises. How do we align interfacing between different domains?

From our requirements, we have well-defined features on a system-level, which are refined into subsystem requirements. These requirements map directly into the interfaces we will need to provide within the respective domains. These should be formulalized in the form of a bridge pattern1.

Note from Author

Add a diagram describing how needs/requirements form interfaces

Summary

  • Establish a healthy developer community and environment
  • Streamline your workflow and processes across departments and teams.
  • Map business needs to development domains and organise architecture around these domains.
  • Provides input to management for organisational structure.
  • Lays the foundation for cross-domain development and cross-department collaboration.
    1. Bridge Pattern