Data Class¶
Flag an object-oriented class that holds fields with getters and setters but no domain methods as a symptom that its behavior migrated outward into consumers, then resolve the verdict with one role question — should this class enforce its own invariants?
Core Idea¶
A data class is an object-oriented code smell: a class holds fields and exposes them via getters and setters but contains no methods performing meaningful domain operations. The behavior that belongs to it has migrated outward into its consumers, violating encapsulation — data and its operations should travel together. The class becomes a passive record, a struct wearing object syntax, with invariants enforced nowhere and validation duplicated across each consumer.
Scope of Application¶
The smell lives within object-oriented software design, across subfields that share encapsulation as their explicit organizing principle.
- Object-oriented design proper — beans with only getters and setters, the everyday review target.
- Layered enterprise architecture — the same condition appears as the "Anaemic Domain Model" critique.
- Domain-Driven Design — a central concern, with rich invariant-owning aggregates as the contrasting target.
- Refactoring practice — a catalogued Fowler smell beside Feature Envy and Shotgun Surgery, fixed by Move Method.
- Modern value-object features — Java
record, Kotlindata class, Python@dataclasslegitimize the no-behavior case.
Clarity¶
Naming the smell makes a hidden verdict legible: two classes with the same syntactic surface can warrant opposite judgments, and the name forces the reviewer to ask the one question the syntax cannot answer — should this class enforce invariants on its own data? It relocates the problem, reframing "this class is too simple" into "where did this class's behavior go, and is it now scattered and inconsistent?"
Manages Complexity¶
A large codebase presents an open-ended worry: somewhere behavior has drifted from its data and validation is diverging. The smell compresses that system-wide audit to a single recognizable local shape — an accessor-only class — then collapses the verdict to one binary parameter: should it enforce its own invariants? Every downstream consequence is read off that answer rather than re-derived per class.
Abstract Reasoning¶
The smell licenses a diagnostic move — reading a thin class as the symptom of behavior that migrated offstage. It does boundary-drawing — resolving a syntactically-undecidable verdict (value object versus anaemic entity) with one role question. It supports an interventionist move — routing to Move Method or record-formalization by that answer. And it is predictive — reading change-cost and severity off the consumer count.
Knowledge Transfer¶
Within object-oriented software the smell transfers as mechanism: the diagnostic, the verdict branch, and the remedies carry intact across enterprise architecture, DDD, and refactoring practice, all sharing encapsulation as an explicit commitment. Beyond the OO paradigm it does not transfer even as a failure — in functional programming and the relational model, separating data from operations is the correct default. What genuinely recurs is the parent structure — the absence of encapsulation and the resulting coupling — not the named code smell.
Relationships to Other Abstractions¶
Current abstraction Data Class Domain-specific
Parents (3) — more general patterns this builds on
-
Data Class is a kind of Code Smell Domain-specific
Data Class is the code-smell species whose passive fields and accessors provide defeasible evidence that behavior and invariant enforcement migrated into consumers.
-
Data Class is part of Coupling Prime
Cross-class coupling is a constituent of the data-class smell because consumers reach into exposed state and carry the displaced behavior.
-
Data Class presupposes Information Hiding Prime
The data-class smell presupposes information hiding because its verdict is that an entity exposes representation and invariants that its behavioral surface was expected to conceal.
Hierarchy paths (7) — routes to 7 parentless roots
- Data Class → Code Smell → Evidence → Provenance → Traceability → Observability
- Data Class → Coupling
- Data Class → Information Hiding → Abstraction
- Data Class → Information Hiding → Boundary
- Data Class → Code Smell → Evidence → Provenance → Attestation → Authentication
- Data Class → Code Smell → Evidence → Provenance → Traceability → Transformation → Function (Mapping)
- Data Class → Code Smell → Evidence → Provenance → Custody Transfer → State and State Transition → Phase Space
Neighborhood in Abstraction Space¶
Data Class sits in a crowded region of the domain-specific corpus (35th percentile for distinctiveness): several abstractions share nearly its structure, so a description that fits it tends to fit its neighbors too.
Family — Unclustered & Miscellaneous (309 abstractions)
Nearest neighbors
- Primitive Obsession — 0.86
- Data Extraction Through Prompting — 0.85
- Insecure Deserialization — 0.85
- Quality inherence — 0.85
- Prompt Injection — 0.84
Computed from structural-signature embeddings · 2026-07-12