Fundamentals 17 min read

Understanding Hexagonal Architecture: Principles and Implementation Example

Hexagonal Architecture, introduced by Alistair Cockburn in 2005 and revived since 2015, separates application, domain, and infrastructure layers using ports and adapters, enabling isolated testing, clear dependency direction, and flexible code organization, illustrated with a console‑based poem‑printing example and detailed implementation guidelines.

Architects Research Society
Architects Research Society
Architects Research Society
Understanding Hexagonal Architecture: Principles and Implementation Example

Hexagonal Architecture, originally described by Alistair Cockburn in 2005 and gaining renewed interest after 2015, is a software architecture style that isolates the core business logic (the domain) from external concerns such as user interfaces, databases, and other infrastructure.

The architecture is built on three core principles:

Explicitly separate the application, domain, and infrastructure layers.

Direct dependencies flow from the application and infrastructure toward the domain.

Use ports and adapters to isolate the boundaries between the domain and the outside world.

These principles allow the same application to be driven by users, automated tests, or batch scripts while keeping the domain independent of any particular runtime or storage mechanism.

In practice, the architecture is visualized as a hexagon with three sides:

Left side (Application): code that interacts with users or external programs (e.g., UI, HTTP controllers, console adapters).

Center (Domain): pure business logic and domain models, free of technical concerns.

Right side (Infrastructure): technical details such as file I/O, databases, or external services.

Communication between these sides occurs through well‑defined interfaces (ports). The application side calls domain ports (e.g., IRequestVerses ), and the domain calls infrastructure ports (e.g., IObtainPoems ). Adapters implement these ports on the outside of the hexagon.

A concrete example is a small console program that prints poems. The domain defines a PoetryReader that depends on an IObtainPoems interface. An infrastructure adapter PoetryLibraryFileAdapter reads poems from a file, while a console adapter drives the domain from the left side.

class Program
{
    static void Main(string[] args)
    {
        // 1. Instantiate right‑side adapter ("go outside the hexagon")
        IObtainPoems fileAdapter = new PoetryLibraryFileAdapter(@".\Peoms.txt");
        // 2. Instantiate the hexagon
        IRequestVerses poetryReader = new PoetryReader(fileAdapter);
        // 3. Instantiate the left‑side adapter ("I want ask/to go inside")
        var consoleAdapter = new ConsoleAdapter(poetryReader);
        System.Console.WriteLine("Here is some...");
        consoleAdapter.Ask();
        System.Console.WriteLine("Type enter to exit...");
        System.Console.ReadLine();
    }
}

The constructor of the domain class shows the dependency inversion:

public PoetryReader(IObtainPoems poetryLibrary)
{
    this.poetryLibrary = poetryLibrary;
}

Running the program produces output such as:

$ ./printPoem
Here is some poem:
I want to sleep
Swat the files
Softly, please.
-- Masaoka Shiki (1867 - 1902)
Type enter to exit...

Because the domain depends only on abstractions, it can be unit‑tested in isolation, and different adapters can be swapped without changing business logic. This aligns with SOLID principles, especially Dependency Inversion and Interface Segregation.

Organizing code within each layer is flexible; the recommendation is to group by business capability rather than technical type (e.g., avoid generic "services" or "repositories" folders). The article also discusses runtime instantiation without a DI framework, showing the order of creating infrastructure, domain, and application components.

Finally, the article notes that while Hexagonal Architecture offers a good trade‑off between complexity and testability, it is not a silver bullet. Alternatives such as Clean Architecture or CQRS may be more appropriate for certain contexts.

TestingDomain-Driven Designsoftware designdependency inversionhexagonal architectureports and adapters
Architects Research Society
Written by

Architects Research Society

A daily treasure trove for architects, expanding your view and depth. We share enterprise, business, application, data, technology, and security architecture, discuss frameworks, planning, governance, standards, and implementation, and explore emerging styles such as microservices, event‑driven, micro‑frontend, big data, data warehousing, IoT, and AI architecture.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.