DEV Community

Cristian Sifuentes
Cristian Sifuentes

Posted on

8 - When Not to Use OOP — The Cost of Abstraction

When Not to Use OOP — The Cost of Abstraction  <br>
*Why the wrong abstraction slows systems, teams, and thinking*

When Not to Use OOP — The Cost of Abstraction

Why the wrong abstraction slows systems, teams, and thinking


Abstraction is not free.

It costs time, cognition, flexibility, and sometimes truth.

This is Part 8 of the series:

  1. Classes in C#: From First Principles to Architectural Mastery
  2. Abstract Class vs Interface — A Systems View
  3. Composition vs Inheritance — The Physics of Change
  4. Encapsulation & Information Hiding — Designing for Ignorance
  5. SOLID Revisited — A Post-Pattern Perspective
  6. Polymorphism — Substitution Over Reuse
  7. Clean Architecture as a Consequence, Not a Pattern
  8. When Not to Use OOP — The Cost of Abstraction

This article is about restraint.

About knowing when not to reach for objects.


The Uncomfortable Premise

Object-Oriented Programming is powerful.

That’s precisely why it’s dangerous when misapplied.

OOP excels at:

  • modeling long-lived concepts
  • enforcing invariants
  • managing change over time

But many problems:

  • are transient
  • are data-centric
  • change shape faster than abstractions can keep up

For those problems, OOP becomes drag.


Abstraction Is a Bet on the Future

Every abstraction is a prediction:

“This shape will remain useful.”

When the prediction is wrong:

  • abstractions calcify
  • workarounds appear
  • complexity leaks

The cost is not paid immediately.
It accrues silently.


The Three Hidden Costs of Abstraction

1️⃣ Cognitive Load

Each abstraction adds:

  • a concept to remember
  • an indirection to follow
  • a decision to understand

Simple code:

var total = prices.Sum();
Enter fullscreen mode Exit fullscreen mode

Over-abstracted code:

_totalCalculator.Calculate(prices);
Enter fullscreen mode Exit fullscreen mode

The second may be “cleaner” —

but only if the abstraction earns its keep.


2️⃣ Change Latency

Abstractions slow change when:

  • behavior is still in flux
  • requirements are exploratory
  • the domain is poorly understood

Early abstraction locks guesses into code.


3️⃣ Semantic Distance

When behavior is hidden behind layers:

  • intent blurs
  • debugging slows
  • truth becomes indirect

Sometimes, the clearest code is the one closest to the data.


When OOP Shines (And When It Doesn’t)

OOP is a great fit when:

  • the domain is stable
  • rules are strict
  • invariants matter
  • behavior evolves slower than structure

Examples:

  • billing systems
  • security models
  • workflows
  • long-lived business rules

OOP struggles when:

  • data flows dominate
  • transformations are linear
  • shapes change frequently
  • performance is critical
  • problems are short-lived

Examples:

  • ETL pipelines
  • analytics queries
  • configuration processing
  • scripts and tooling
  • glue code

The DTO Illusion

Many systems use OOP but end up with:

  • anemic models
  • logic elsewhere
  • objects as mere bags of data

At that point:

  • OOP adds ceremony
  • without delivering invariants

If behavior doesn’t live with data,

the abstraction is hollow.


Functional and Data-Oriented Alternatives

Sometimes, the right answer is:

  • plain data structures
  • functions
  • pipelines
  • immutability
prices
    .Where(p => p > 0)
    .Select(ApplyDiscount)
    .Sum();
Enter fullscreen mode Exit fullscreen mode

No objects.
No hierarchy.
No ceremony.

Just intent.


The Law of Leaky Abstractions (Still Applies)

Joel Spolsky’s law applies brutally to OOP:

All non-trivial abstractions leak.

When leaks dominate:

  • developers bypass abstractions
  • invariants erode
  • trust disappears

At that point, abstraction becomes liability.


Architecture Is About Proportion

The question is not:

“Should we use OOP?”

The real question is:

“How much abstraction does this problem deserve?”

Too little → chaos

Too much → paralysis

The art is in the balance.


Signals You Should Not Use OOP (Yet)

  • You don’t know the domain well
  • Requirements change weekly
  • Objects have no behavior
  • Interfaces exist “just in case”
  • The simplest solution looks verbose

These are warning signs, not failures.


A Practical Heuristic

Start concrete.

Abstract only under pressure.

Stop when the abstraction pays rent.

This heuristic outperforms most design rules.


The Mental Model to Keep

Abstraction amplifies both clarity and confusion.

Use it where clarity compounds.

Avoid it where confusion multiplies.


Final Takeaway

Junior developers ask:

“Is this object-oriented enough?”

Senior engineers ask:

“Is this abstraction earning its cost?”

That question will save you years.


✍️ Cristian Sifuentes

.NET / C# • Architecture • Systems Thinking

Power is knowing what not to use.

Top comments (0)