Software Design

17 articles

Subdomains and Bounded Contexts in Domain-Driven Design

A large domain modelled as a single unified system produces a model that satisfies no one. This article explains what subdomains and bounded contexts are, why they are not the same thing, and how the boundaries between them are a deliberate design decision.

domain-driven-design

What Is Domain-Driven Design?

Domain-driven design is about building software that reflects the business it models, not just the data it stores. This article explains the core ideas behind DDD: why it exists, what a domain model actually is, and when the approach is worth the investment.

domain-driven-design

Making Invalid States Unrepresentable in Kotlin

Kotlin sealed classes and Arrow’s Either can eliminate entire categories of bugs at compile time. This article shows how to apply them to a hexagonal architecture domain model to make invalid states unrepresentable and turn hidden exceptions into explicit method signatures.

architecture kotlin arrow

Hexagonal Architecture With Ktor and Exposed

The same hexagonal architecture patterns that work in Spring Boot translate directly to Ktor and Exposed. This article shows how, and where a lighter stack makes keeping business logic free from framework concerns more straightforward than it is with Spring Boot.

architecture ktor exposed kotlin

Hexagonal Architecture With Spring Boot

A practical, hands-on guide to building a Spring Boot application with Hexagonal Architecture. The article walks through separating business logic and infrastructure into modules, implementing ports and adapters, and testing the system with fast acceptance, integration, and end-to-end tests.

architecture spring-boot

Hexagonal Architecture Explained

Hexagonal architecture, introduced by Alistair Cockburn, separates business logic from infrastructure using ports and adapters. This article explores the limitations of traditional layered architecture, explains how hexagonal architecture applies dependency inversion, and shows how to implement and test applications in isolation for better maintainability, flexibility, and long term code quality.

architecture

Code Quality Checks

Code quality often deteriorates over time, especially in legacy projects, slowing development and introducing bugs. Using code reviews, static analysis, and dynamic analysis helps detect issues early, while fast feedback loops prevent problems from accumulating. Combining these practices with continuous monitoring ensures cleaner, more maintainable code.

best-practices

Code Smell: Dead code

This post explains why unused or unreachable parts of a project are a common warning sign in aging systems. It outlines how changing requirements and incomplete cleanups create unnecessary leftovers. The article focuses on practical ways to remove this clutter and keep projects lean and maintainable.

code-smells

Code Smell: Large Class

This post examines why overly large classes make code harder to understand, maintain, and test. It outlines strategies for splitting classes, creating subclasses, or defining interfaces to clarify responsibilities. Refactoring in this way promotes better design, easier testing, and greater code reuse.

code-smells

Avoiding Unnecessary Null Checks

Null checks are a common source of bugs and clutter in code. This article explores ways to avoid returning or passing nulls, including using the Null Object pattern, throwing exceptions, and designing objects that encapsulate behavior. By eliminating nulls, you simplify code, reduce errors, and encourage cleaner design.

best-practices