January 6 2025
When to Abstract and When to Keep It Simple
How to decide whether a new layer is helping or whether the code is still better when it stays direct.
Andrews Ribeiro
Founder & Engineer
3 min Intermediate Systems
The problem
There is a very common moment in development:
you see two similar things and think:
I should abstract this now so I do not repeat myself.
Sometimes that helps.
Very often it does not.
Because the abstraction arrives before the understanding does.
And when that happens, the team gets:
- one more layer
- nicer names
- less clarity
- more cost when something needs to change
Mental model
Think about it like this:
abstraction is the act of compressing a pattern that has already become clear enough to deserve its own shape.
If the pattern is still fuzzy, the abstraction is not compressing understanding.
It is compressing uncertainty.
And compressed uncertainty usually comes back as:
- too many optional props
- weird parameters
- special cases
- an internal API nobody really understands
Breaking it down
Check whether the code changes for the same reason
This is the most useful test.
If two pieces of code look similar but are likely to evolve for different business reasons, abstraction can glue together things that should stay separate.
That is where the trouble starts.
Compare the cost of repetition with the cost of a new layer
A small amount of local repetition can be cheaper than:
- creating the helper
- naming the helper
- explaining the helper
- changing the helper when the third case arrives
Not every duplicated line deserves architecture wrapped around it.
Prefer simplicity while the pattern is still maturing
If you are still discovering the variations, direct code often teaches more than a generic layer.
Later, once the pattern becomes clear, abstraction gets much easier and much safer.
Good abstraction reduces questions
A good layer makes the reader ask fewer questions.
A bad layer makes the reader ask:
- what does this really do?
- when does it stop working?
- why does this parameter exist?
If the abstraction increased the number of questions, it made the code worse.
Simple example
Imagine three notification flows.
All of them seem to do this:
- build a message
- call a provider
- store the result
The first impulse is to create a highly generic sendNotification().
But looking closer:
- one flow is marketing
- one is a security alert
- one is an operational confirmation
Now retry rules, audit needs, and priority are already different.
At that point, the better move may be to keep things explicit for a while.
Once it becomes clear what is truly shared, then you can extract the right layer.
Common mistakes
- abstracting too early just to satisfy DRY
- treating small repetition as a bigger problem than structural confusion
- joining behaviors that change for different reasons
- creating a generic API full of flags, parameters, and exceptions
How a senior thinks
More experienced engineers often ask:
Is this abstraction happening because the pattern is mature, or because I feel uncomfortable seeing repetition?
That difference matters a lot.
Seniority here is not making the code look more sophisticated.
It is knowing when it is still better to keep things simple.
What the interviewer wants to see
In interviews, this topic tests design judgment.
The interviewer wants to see whether you:
- distinguish acceptable repetition from dangerous coupling
- avoid premature abstraction
- think about maintenance cost, not only elegance
- can defend simplicity without sounding careless
A strong answer often sounds like this:
I abstract when the pattern is already clear and when the new layer reduces reading and maintenance cost. If I am still discovering the variations, I usually keep the code more direct for a while.
Good abstraction reduces cost. Early abstraction mostly redistributes confusion.
Sometimes the more senior move is resisting the urge to be clever too early.
Quick summary
What to keep in your head
- Abstraction is worth it when it reduces reading cost and change cost, not when it only hides repetition.
- A little honest duplication can be cheaper than a generic layer created too early.
- If the pattern has not matured yet, abstracting too soon usually freezes a bad idea.
- Simple code is not inferior code. Very often it is just code with less vanity and more clarity.
Practice checklist
Use this when you answer
- Can I explain why small repetition does not always require abstraction?
- Do I know how to test whether two pieces of code really change for the same reasons?
- Can I spot the signs of premature abstraction in a real codebase?
- Can I answer an interview question by defending a simpler structure without sounding improvised?
You finished this article
Share this page
Copy the link manually from the field below.