I once joked that the real purpose of Object-Oriented Programming (OOP) is to treat business concepts like they’re your pets. It usually gets a laugh, but the more I sit with the idea, the more uncomfortable it becomes because it’s actually true.
And I don’t mean this in a “Gang of Four” design pattern way. I mean it in the visceral way you understand ownership when you’ve shipped real systems for decades.
The Mental Model of Ownership
If you’ve ever had a pet, you know a few things instinctively:
You name it.
You know exactly what it’s allowed to do.
You know what it should never do.
You don’t let random strangers mess with it.
And when something is wrong, you can usually tell immediately.
That is the mental model OOP was originally trying to give us. It wasn’t about inheritance hierarchies, UML diagrams, or abstract factories with heroic names. It was about ownership.
Business Objects Are Not Data Bags
Somewhere along the way, we started calling things “objects” that clearly aren’t. They are structs, DTOs, or just ORM output with a class wrapper. You see it when code looks like this:
PHP
$customer->status = 'suspended';
$customer->credit_limit = 0;
$customer->vip = false;
Nothing stops you from writing this. Nothing explains why the customer is suspended. Nothing enforces the rules. Anyone can reach in and flip switches. That isn’t an object; that is a spreadsheet cell with delusions of grandeur.
An actual object (a “pet”) looks boring but behaves safely:
PHP
$customer->suspend($reason);
Why is this better? Because the Customer owns its behavior. You don’t mutate it; you ask it to do something. That is the pet relationship. You are responsible for the object’s well-being, which means protecting its internal state from the chaos of the outside world.
This Is Why DDD Exists
Domain-Driven Design (DDD) didn’t appear because architects wanted more layers to manage. It appeared because we kept breaking systems by letting anyone touch anything.
DDD is effectively a formal way of saying: Business rules belong with the business concept.
They don’t belong in controllers, random services, or scattered across “helper” classes, or in the worst case, duct-taped into a random WordPress hook or filter. If a rule exists because the business exists, it belongs with the object that represents it. This isn’t dogma; it’s damage control.
The Legacy of “Old” Tools
Back when I was building systems in VB, VB.NET, or FoxPro, this wasn’t a philosophical debate. A button clicked, a form reacted, and a private sub handled the logic. If something was Private, it was private. End of discussion.
We didn’t have time to argue about architecture because we were busy shipping software people used every day. Ironically, those systems often felt more “object-oriented” than modern code because the ownership was obvious.
Today, we often have “domain models” with no behavior, services that do everything, and objects that exist purely to be passed around. We call it OOP because the files end in .php or .ts, but there is no ownership. When no one owns an object, it becomes fragile. When everyone can mutate it, it becomes dangerous.
Architecture is About Care
DDD feels heavy when you fight it, but natural when you realize it’s just enforcing what you already believe: Don’t let random code mess with business state. Make invalid states unrepresentable by default.
If there is one takeaway here, it’s this: If nobody feels responsible for an object, it’s not an object—it’s a liability.
Good OOP and good DDD aren’t about elegance. They are about care. You don’t throw your pets around, you don’t expose their insides, and you don’t let strangers decide how they behave. That’s not ideology. That’s just how systems survive.


