| name | data-oriented-architecture |
| description | Apply when encountering switch/if-else dispatch on entity type, designing entity systems, or refactoring toward extensibility. Provides registry-based dispatch, capability composition, and infrastructure-first patterns. Complements solid-architecture. |
Data-Oriented Architecture Patterns
When To Use This Skill
Activate this skill when:
- Encountering switch statements or if/else chains dispatching on entity/object type
- Designing systems with multiple variants of similar entities
- Refactoring code where adding new types requires changes in multiple locations
- Building plugin systems, handler registries, or factory patterns
- Noticing the "expression problem" (hard to add new types AND new operations)
Core Principle
Separate data from behavior, dispatch via registry.
Entity = Pure Data (what it IS) + type discriminator
Definition = Bundled Behavior (what it DOES)
Registry = Type → Definition mapping (HOW to dispatch)
Pattern 1: Registry-Based Polymorphism
Problem
Switch statements scattered throughout codebase:
// Scattered in rendering.ts
switch (entity.type) {
case 'typeA': renderA(entity); break;
case 'typeB': renderB(entity); break;
}
// Scattered in update.ts
switch (entity.type) {
case 'typeA': updateA(entity); break;
case 'typeB': updateB(entity); break;
}
// Adding new type = edit N files
Solution
Single registry bundling all type-specific behavior:
// definitions.ts - ONE location for all type-specific code
const DEFS: Record<EntityType, Definition> = {
typeA: { render: renderA, update: updateA, ... },
typeB: { render: renderB, update: updateB, ... },
};
// Consumers dispatch generically
DEFS[entity.type].render(entity, ctx);
DEFS[entity.type].update(entity, dt);
// Adding new type = ONE registry entry, ZERO consumer changes