🏢 Enterprise, Application & DDD Patterns

Application structure

PatternWhatWhenOrbit usage
LayeredController → service → repositorySimple CRUDAdmin CRUD
Hexagonal (Ports & Adapters) ⭐Domain core; ports = interfaces; adapters = web/DB/LLM/KafkaCore domains with many integrationsEngine core independent of Postgres/Kafka
Clean / OnionDependency rule points inwardSame idea, more ceremony—
Vertical slicesOrganize by featureMany independent featuresUse-case modules
Modular monolith ⭐Enforced module boundaries in one deployableDefault startorbit-api with Spring Modulith

Data access (Fowler, PoEAA)

PatternNotes
RepositoryA collection-like interface for aggregates (Spring Data)
Unit of WorkTrack changes, commit once (Hibernate Session / persistence context)
Identity MapOne object per row per session (first-level cache)
Data Mapper vs Active RecordJPA/sqlc (mapper) vs Rails-style (record)
Lazy LoadProxies; the root of N+1
SpecificationComposable query predicates (Spring Data Specifications)
DTO / projectionShape data for the API; never leak entities
Transaction Script vs Domain ModelProcedural per use case vs rich objects; choose by domain complexity

DDD, strategic

  • Bounded context (Orbit: Tenancy, Workflow Authoring, Execution, Knowledge, Tooling, Billing)
  • Ubiquitous language (run, step, attempt, lease, signal)
  • Context map: customer/supplier, conformist, anti-corruption layer (around LLM provider APIs!), shared kernel, published language (protobuf events)
  • Subdomains: core (execution engine) vs supporting (tool registry) vs generic (auth → buy Keycloak)

DDD, tactical

PatternRuleOrbit example
EntityIdentity over timeRun, Workflow
Value objectImmutable, equality by valueTokenUsage, Money, RetryPolicy
Aggregate ⭐A consistency boundary; modify one aggregate per transaction; reference others by IDRun (with its steps)
Domain eventSomething happened (past tense)StepCompleted, ApprovalRequested
Domain serviceLogic that doesn’t fit an entityRoutingPolicyEvaluator
FactoryComplex creation with invariantsRun.start(definitionVersion, input)

Integration patterns

Outbox · Inbox / idempotent receiver · Saga (orchestration/choreography) · Process manager · CQRS · Event sourcing · Materialized view · API composition · BFF · Strangler fig · Branch by abstraction · Feature toggles → details in Distributed & Cloud Patterns

🔬 Katas

  • Draw Orbit’s context map with the relationship types
  • Find an aggregate boundary mistake: put Workflow and Run in one aggregate → contention analysis → split them
  • ArchUnit tests that enforce hexagonal rules in orbit-api (domain must not import Spring/JPA)
  • Write the same use case as a Transaction Script and as a Domain Model; list the trade-offs