Overview

4 Domain Modeling with Algebraic Data Types

In this chapter, the author walks through a deliberately messy, real-world style design process for a rocket-manufacturing checklist feature, using the friction in the code as a signal that the model and the domain meaning are drifting apart. The narrative starts from vague requirements and repeatedly refines them by asking what the data really means, rather than by adding behavior or defensive code first. Along the way, the checklist is split into distinct concepts such as templates, instances, and step status, showing how careful modeling can replace ambiguity with structure.

The core lesson is that records are best understood as modeling AND: each field contributes to a cartesian-product style combination of attributes. That makes records powerful for expressing things that belong together, but dangerous when unrelated states are forced into one type, because the result is often nulls, illegal combinations, and lots of validation code. The chapter demonstrates this with a checklist status model that first seems simple, then becomes awkward as completion and skipping metadata are added, and finally improves when those contextual attributes are recognized as describing distinct states rather than one overloaded record.

To model those distinct states, the chapter introduces sealed interfaces as a way to express OR: a checklist status is one of several permitted variants, and no others. This creates a closed family of data types that matches the domain more precisely, makes illegal states impossible to represent, and reduces the need for defensive programming. The chapter then ties these Java features to algebraic data types, explaining records as product types and sealed interfaces as sum types, and showing how their algebraic laws can guide safe refactoring and help developers reason about meaning, invariants, and valid state spaces more clearly.

The checklist!
A more complete view of checklists
refactoring the attributes
refactoring to remove the individual Booleans
What our code says versus what it actually means
Approximating what we actually mean from multiple semantic readings of the same code
comparing the conflicting meanings between our data and our code
the Statuses are well modeled, but nothing ties them together under a single idea
What we want
Viewing Records and Product Types as the cartesian product of sets
algebra as a sketching language
using different symbols doesn’t change the underlying semantics
Algebraic types can be represented symbolically
Operations on types follow many of the same rules as “regular” multiplication and addition
Numbers denote how many values a type can contain
Sophisticated ideas can like optionality can be encoded as Product and Sum Types
It’s worth spending some time proving to yourself that these are all the same!
The Java model represented as Algebraic Product and Sum types
Applying the distributive law over Sum and Product types to factor out duplication
Translating from the refactored algebraic types to refactored Java records and interfaces

Summary

  • “Representation is the essence of programming”
  • In data-oriented design we focus on the representation of the data and what it means rather than the state and its operations
  • Design is an iterative and messy process (and that’s OK!).
  • Defensive programming is a warning sign that the meaning of the code might be out of line with the meaning of the data
  • We have to train ourselves to become sensitive to when we start relying on English prose that lives in the code to convey to readers where the code itself is wrong
  • There is an implicit AND between every attribute we define on a record
  • If we don’t pay attention, we can AND attributes together that have conflicting meanings and cause our code to lose focus
  • When we design consciously, we can use AND to push our data modeling in good directions.
  • We have to be on the lookout for when we’re using AND instead of OR
  • Interfaces can represent more than just behaviors. They can represent data types
  • Sealed classes and interfaces allow us to express “these options and no others”
  • Records and Sealed Interfaces are how we represent Algebraic Data Types in Java
  • Product Types are built with the × operator and combine type with AND
  • Sum Types are built with the + operator and combine types with OR

FAQ

What is the main goal of domain modeling in this chapter?The main goal is to model the meaning of the domain data as accurately as possible, so the code reflects the real-world concept instead of forcing defensive programming or allowing invalid states.
Why does the chapter focus so much on the “messy” design process?Because real design is iterative and often includes wrong turns. Showing the friction and missteps helps you recognize when a model is not matching the domain’s meaning.
What is the difference between a checklist Template and an Instance?A Template is a named collection of things to do, while an Instance is a named run-through of that template at a particular point in time where the work is actually performed and recorded.
Why was the initial Step model with isCompleted considered wrong?Because completion is not part of what a step is in a template. Putting isCompleted on Step allowed nonsensical states, like steps being already completed inside the template itself.
What does “making illegal states impossible to represent” mean?It means designing your types so that invalid combinations of data cannot even be expressed in code, which removes the need for lots of defensive checks later.
Why did adding completedBy and completedOn to one Status record cause problems?Because those fields only make sense when a status is completed, but the single record forced them to exist for all statuses. That created contextual meaning, nulls, and illegal states.
How did the chapter solve the completed-status modeling problem?It split the idea into a separate Completed record containing only the fields that belong to that state. This removed the invalid combinations and made the constructor unnecessary for enforcing those rules.
How are records used in this chapter as a modeling tool?Records model product types, meaning they combine attributes with an implicit AND. They are used to represent data that belongs together in one state.
How do sealed interfaces help model checklist statuses?They model OR relationships by defining a closed set of possible status types, such as NotStarted, Completed, and Skipped, all under one parent type.
What is the relationship between Algebraic Data Types, records, and sealed interfaces in Java?Records correspond to product types, which combine values with AND. Sealed interfaces correspond to sum types, which choose between alternatives with OR. Together, they form Java’s version of Algebraic Data Types.

pro $24.99 per month

  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose one free eBook per month to keep
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime

lite $19.99 per month

  • access to all Manning books, including MEAPs!

team

5, 10 or 20 seats+ for your team - learn more


choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Data-Oriented Programming in Java ebook for free
choose your plan

team

monthly
annual
$49.99
$499.99
only $41.67 per month
  • five seats for your team
  • access to all Manning books, MEAPs, liveVideos, liveProjects, and audiobooks!
  • choose another free product every time you renew
  • choose twelve free products per year
  • exclusive 50% discount on all purchases
  • renews monthly, pause or cancel renewal anytime
  • renews annually, pause or cancel renewal anytime
  • Data-Oriented Programming in Java ebook for free