Member-only story
Atomic Vertical Slicing vs Horizontal Layered Architecture— Beyond the ‘Service’ Suffix — e.g. CarService — Toward Functional Single Responsibility with Atomicity
In many codebases, the use of UserService
, CarService
, or any other [Noun]Service
is a common convention. I’ve been using that convention for many years. But now let’s look at it again to question its real intent. At first glance, it may seem like a valid separation of concerns. After all, we’re just grouping domain-related operations under a domain-named class. But is that truly single responsibility? Or is it merely noun-based technical separation of concerns?
I’ve been reflecting on this distinction, and I’ve come to believe that [Noun]Service
often masks a deeper problem: lack of clear functional separation. While there’s no universal rule in software architecture—context always matters—there are principles that can guide us toward cleaner, more maintainable structures.
Let’s take a closer look.
The Illusion of Single Responsibility
Say we have a CarService
class in our business logic layer. Over time, it accumulates methods like:
addEngine()
,addTransmission()
,addMirror()
,addBumper()
,addWheel()
,addSeats()
,addDoors()