DEV Community

Alejandro Navas
Alejandro Navas

Posted on • Edited on

One simple naming trick that keeps vibe-coded code from rotting

In I Shall Call It… SomethingManager, Jeff Atwood criticized names such as:

SessionManager
ConnectionManager
UrlManager
Enter fullscreen mode Exit fullscreen mode

Manager tells us that a class does something with something.

Useful.

We mostly stopped calling everything Manager. We now call it:

UserService
PaymentHandler
OrderProcessor
AccountHelper
Enter fullscreen mode Exit fullscreen mode

The suffix changed. The ambiguity survived.

Vague names permit vague code

What belongs in UserService?

register()
resetPassword()
mergeAccounts()
assignRole()
calculateDiscount()
Enter fullscreen mode Exit fullscreen mode

All of these involve a user.

That is where their architectural similarity ends.

They have different rules, dependencies, side effects, security concerns, and reasons to change. But the name objects to none of them.

UserService is not a boundary. It is permission.

Now compare:

UserRegistrar
PasswordResetter
AccountMerger
RoleAssigner
DiscountCalculator
Enter fullscreen mode Exit fullscreen mode

These are agentive names. They name the component responsible for a capability.

Their value is not grammatical elegance. Their value is resistance.

If PasswordResetter starts calculating discounts, the mistake is visible before opening the file.

Inside UserService, it looks perfectly employed.

Names shape dependencies

This dependency graph appears plausible:

UserService
├── EmailSender
├── PaymentGateway
├── PermissionRepository
├── AuditLogger
└── DiscountCalculator
Enter fullscreen mode Exit fullscreen mode

Users interact with all of those things.

This one tells a more specific story:

PasswordResetter
├── UserFinder
├── ResetTokenIssuer
└── ResetEmailSender
Enter fullscreen mode Exit fullscreen mode

If PasswordResetter suddenly needs InvoiceGenerator, someone has to explain why.

That friction is useful.

A precise name narrows the responsibilities and dependencies that look natural. It does not prevent bad design, but it removes its camouflage.

Naming exposes decomposition problems

Sometimes a component cannot be given a specific name without lying.

So we call it:

Manager
Service
Adapter
Handler
Processor
Enter fullscreen mode Exit fullscreen mode

That is usually treated as a naming problem.

It may be a design problem.

If one class registers users, resets passwords, assigns roles, calculates discounts, and merges accounts, there may be no honest short name for it.

That is information.

The difficulty of naming the component is evidence that the component does not represent one coherent responsibility.

Split the responsibilities, and the names tend to appear:

UserRegistrar
PasswordResetter
RoleAssigner
DiscountCalculator
AccountMerger
Enter fullscreen mode Exit fullscreen mode

The names did not create the design.

They made the missing design difficult to ignore.

Names make composition visible

Large capabilities are often built from smaller ones.

OrderPlacer
├── CartValidator
├── PriceCalculator
├── InventoryReserver
├── PaymentCollector
└── ConfirmationSender
Enter fullscreen mode Exit fullscreen mode

The OrderPlacer owns the sequence. The collaborators own their rules.

Without names for those responsibilities, the same design often becomes a long method inside OrderService, separated by comments explaining the components that were never created.

Agentive naming gives responsibilities an address.

That makes them easier to test, replace, reuse, and compose.

It does not mean creating one class for every verb. That would merely replace noun-oriented bureaucracy with verb-oriented bureaucracy.

The rule is simpler:

Give a responsibility a name precise enough that unrelated behaviour looks dishonest.

This is not architecture

Agentive naming is not an architectural pattern.

It is just naming.

But names influence what responsibilities look natural. Responsibilities influence dependencies. Dependencies become architecture.

So “just naming” is doing rather more work than advertised.

Good names do not guarantee good software.

They make bad software harder to disguise.

This matters more with AI

AI coding agents infer structure from the code already present.

Give them:

UserService
PaymentManager
OrderProcessor
Enter fullscreen mode Exit fullscreen mode

and they will confidently place the next responsibility into the nearest vague container.

At considerable speed.

Give them:

PasswordResetter
RefundIssuer
OrderCanceller
Enter fullscreen mode Exit fullscreen mode

and the intended boundaries are easier to infer.

Your codebase is now also a prompt.

Vague names teach vague design. AI merely industrializes the lesson.

Naming is a weak type system for responsibility.

UserService is any.

Top comments (0)