Catalog / Data-Oriented Patterns / DOP: Schema-Based Validation
DOP

DOP: Schema-Based Validation

Separate data schema from data representation. Validate data dynamically via explicit contracts.

Intent & Objective

Do not lock validation rules inside class constructors. Instead, allow data to flow freely as transparent records or generic maps, and validate it using decoupled schema validators or pattern matching.

πŸ‘₯ Real-World Human Analogies & Social Roles
1 Intuitive Scenarios
Airport Passport Control Border Security

"The passport contains raw data; the border control checkpoint applies external validation rules dynamically."

The Problem

Rigid constructor validation prevents partially-filled forms, drafts, and progressive data enrichment. When business validation rules change, class definitions break and old persisted objects fail to deserialize.

The Solution

Separate the validation specification into independent schema functions or validators. Check valid states explicitly at system boundaries (API ingress, database commits).

Key Participants & Architectural Roles

Raw Data
Unvalidated transparent record or dictionary
Schema / Specification
Set of rules or predicates describing valid shapes
Validation Function
Pure function: `(Data, Schema) -> Result<ValidData, Errors>`

Code Samples (Traditional OOP vs Functional Programming)

Available in C++, Python, and Java

Paradigm Contrast: Traditional OOP vs Functional / Data-Oriented

In OOP, validation is hardcoded into constructors and setters (`if (age < 0) throw`). In DOP, data representation is separated from validation rules, allowing the same data structure to be validated against multiple schemas (e.g., DraftSchema vs PublishSchema).

Advantages

  • βœ“ Allows storing and passing drafts or intermediate states without crashing
  • βœ“ Supports multiple distinct validation contexts (e.g. relaxed draft vs strict submission)
  • βœ“ Decouples business validation from object serialization

Trade-offs

  • βœ— Requires explicit invocation of validation checks at system boundaries

When to Apply

  • β†’ Handling external payloads from APIs, user forms, and JSON messages
  • β†’ Multi-step wizard processes where data is incomplete until the final step

When to Avoid

  • ! When an entity has strict compiler-enforced primitive invariants that never vary across any context