DOP: Separate Code from Data
Code lives in pure functions; data lives in passive, transparent data structures without encapsulated methods.
Intent & Objective
Decouple data representation completely from behavior. Instead of locking data inside objects with private fields and member methods, treat data as plain, transparent records or maps, and place all business logic in pure, stateless functions.
"The order ticket is a plain sheet of data with no methods. The chefs (code) read the data, prepare dishes, and print receipts without mutating the ticket structure."
The Problem
In traditional OOP, adding a new method to a domain entity (e.g. `User.exportTaxReport()`, `User.serializeXml()`) pollutes the class with foreign dependencies and forces recompilation of the entire object hierarchy. When two systems need to exchange data, OOP forces heavy object-relational mapping (ORM) and DTO conversions.
The Solution
Define data as plain transparent records (C++ structs, Python dataclasses/dicts, Java records). Write standalone functions in modules or namespaces that take data as input and return transformed data as output.
Key Participants & Architectural Roles
Code Samples (Traditional OOP vs Functional Programming)
Available in C++, Python, and JavaParadigm Contrast: Traditional OOP vs Functional / Data-Oriented
In OOP, data and logic are welded together inside class instances (`object.method()`). In Data-Oriented Programming (DOP), data and code are strictly separated (`function(data)`). This eliminates anemic domain model debates and allows business logic to evolve without altering data representations.
Advantages
- β Infinite composability: any function can process any compatible data structure
- β Effortless serialization to JSON, XML, or binary formats without reflection or custom mappers
- β Trivial unit testing: pure functions only require passing input data and asserting output data
Trade-offs
- β Lack of class-level encapsulation means any code can read all data fields if not bounded by modules
When to Apply
- β Modern web services, microservices, and event-driven data pipelines
- β When the same data entity needs to be processed by dozens of different subsystems (billing, analytics, notifications)
When to Avoid
- ! Stateful GUI widget toolkits where UI elements naturally encapsulate internal widget state and OS window handles