DispensablesLow

Data Class: What It Costs and How to Fix It

A class that contains only fields and getters/setters with no meaningful behaviour of its own.

Annual Cost$1k - $8k
Severity
2/5
CategoryDispensables
Detection4 tools

What It Is

A Data Class is a class that holds data but performs no operations on that data. All behaviour that uses the data lives in other classes, which reach into the Data Class to get the values they need. In languages with records or data classes as a first-class feature (Kotlin data classes, Python dataclasses, TypeScript interfaces), this is sometimes intentional and appropriate. The smell arises when the Data Class should have behaviour but developers have moved all logic to consuming classes instead, violating the 'Tell, Don't Ask' principle.

Threshold: A class with only getters/setters in an OO language is a Data Class. In TypeScript/Kotlin where data classes are idiomatic, the smell only applies when the class should have behaviour but does not.

Why It Costs Money

1

Feature Envy cascades. When behaviour is separated from its data, every class that uses the data must reach in, extract values, perform logic, and put results back. This creates Feature Envy in every consumer and duplicates the logic.

2

Validation is scattered. Without behaviour, the Data Class cannot enforce its own invariants. Validation rules for the data are duplicated across every consumer, each potentially implementing them differently.

3

Encapsulation is broken. Clients depend on the internal structure of the Data Class. If you add, remove, or rename a field, every consumer must update.

Specific Cost Mechanisms

  • Duplicated logic: behaviour that should be in the Data Class is scattered across consumers
  • Validation inconsistency: different consumers validate the data differently
  • Structural coupling: consumers depend on field names and types, not behaviour

Estimated Annual Cost

Cost per instance by team size and codebase size. Based on $120,000 average developer salary. See full methodology.

Team SizeSmall (<50k LOC)Medium (50k-200k)Large (200k+)
3 devs$1,000$2,400$4,800
5 devs$1,600$4,000$8,000
10 devs$2,500$6,000$8,000
20 devs$3,200$8,000$8,000

How to Detect It

Specific rules and thresholds for automated detection. See full tool comparison.

SonarQube
squid:S1104 / squid:S2387

Public fields, missing encapsulation

CodeClimate
method-count

Classes with only accessor methods and no behaviour

PMD
DataClass

Directly detects classes with only getters/setters

IntelliJ IDEA
Data class inspection

Suggests moving behaviour to data-holding classes

Refactoring Patterns

Proven techniques to eliminate this smell. See all refactoring patterns.

Move Method

Logic in consumers operates primarily on the Data Class's fields

Effort: 1-3 hours per method
Impact: Centralises logic and enables consistent validation

Encapsulate Field

Public fields are accessed directly

Effort: 30-60 minutes per field
Impact: Adds controlled access and validation at the source

Encapsulate Collection

The class exposes mutable collections

Effort: 1-2 hours
Impact: Prevents external mutation and enables change notification

Related Smells