
Explore data oriented programming in modern Java, moving beyond rigid responses to rich data models for microservices, with modern features like records and pattern matching.
Set up a Java data oriented programming playground in IntelliJ with Maven, Java 24, and essential dependencies like logback and Jackson to learn records, sealed types, and pattern matching.
Java records automatically generate constructors, getters named after fields, and equals, hashCode, and toString methods. They enable clean data modeling with record components and reduce repetitive work.
Practice coding with me as we explore Java records and their best practices, while organizing code with sectioned packages like section zero one to keep projects orderly and revisitable.
Explore Java records by using an inner person record, inspect getters and to string, and see how the auto-generated equals and hash code require all components to match.
Master how to tailor a canonical constructor for a Java record to enforce a business rule, like uppercasing the last name, without rewriting every field.
Explore the compact constructor as a shorthand for the canonical constructor, enabling field modification during record initialization, with examples like uppercasing the last name.
Apply compact constructors to enforce validation rules during object creation, ensuring non-null last name and minimum age before initialization, using records or Jakarta validation annotations when appropriate.
Use a non-canonical constructor to delegate to the canonical constructor in a record, enabling creation with only a title while defaulting the date to today.
Java records are not truly immutable; record components are final, but a mutable list can be altered unless a defensive copy is used in a compact constructor.
Override accessor methods in records to customize behavior without changing signatures, using examples like uppercasing last names or providing optional defaults via separate methods.
Explore how to handle nullable fields in Java records, using compact constructors for validation and optional to represent nullability, while designing clean APIs with non-canonical constructors for convenience.
Learn why Java records cannot have extra instance fields, and how to use record components and instance methods like full name to keep data simple and predictable.
Explore how static members work in records by creating a price record with a private static final USD constant and a static factory method that returns a price instance.
Show how records can implement interfaces by using a record email template that implements the unary operator of string, illustrating map operator on a stream of customers to welcome messages.
Explore how to inspect Java records at runtime by checking if a type is a record, listing its components and types, and retrieving component values via reflection.
Organize records in a large java project by using separate java files, domain- or feature-specific groupings, nested records, or private inner records, choosing the approach by use case.
Explains how Java record classes serve as immutable data carriers with private final components, auto-generated accessors, and methods like equals, hashCode, and toString, plus canonical and compact constructors.
Explain the sealed modifier in Java 17, a tool to restrict class hierarchies and reduce runtime surprises, a key concept in data oriented programming with Honda and Toyota car examples.
Explore the sealed modifier by modeling a sealed payment hierarchy with cash and credit card as the permitted subclasses, organized into packages to enforce compile-time constraints.
Explore sealed types to restrict subclassing, creating a cash rewards class that extends cash with permits, and override process to add one reward point per dollar.
Explore sealing an interface and implementing it with records for a payment system, using credit card and PayPal records, with explicit permits and a simple demo class.
Explore how records act as immutable data carriers and how a side-effecting payment method with no return fits into sealed types, using this simple example to illustrate pattern matching.
Explore how sealed types enable data oriented programming, enforcing hierarchies with abstract sealed classes and sealed interfaces, and learn why extending or implementing classes must use sealed, unsealed, or final.
Explore pattern matching with instanceof and switch expression to test and unpack objects, and learn why instanceof can be a code smell versus polymorphism handling behavior in animal examples.
Explore pattern matching in java with the instanceof pattern variable, its scope and behavior across nulls and strings, and how switch expressions may simplify code.
Explore the modern switch expression in a country-based tax example, avoiding fall-through, handling nulls and defaults, and using yield for multi-line cases.
Explore type pattern and pattern variables with switch expressions to replace complex if-else chains, demonstrating null, string, collection, map, and array cases in Java.
Demonstrate pattern label dominance in a java switch, showing that multiple labels may match an object, but only a single block executes based on case order and type checks.
Discover how the guarded pattern label uses a when clause to guard an integer type and value, printing negative integers when i is negative and accessible as a pattern variable.
Explore Java’s type-based pattern matching to accept objects by type, ignore values with the underscore, and print 'received int' or 'received double' without using the matched payload.
Explore how the record pattern enables deconstructing an API response record in Java using a switch expression, extracting success data and handling errors like timeouts with pattern variables.
Master the nested record pattern by deconstructing product and user records, using recursive access to product name, price, and user email.
Master the switch exhaustiveness concept by covering all input values with enums, avoiding default when complete, and handling null cases for robust code.
Master pattern matching in Java with instanceof and switch expressions to safely extract data using pattern variables and guarded patterns. Explore modern switch semantics, yield blocks, and record pattern deconstruction.
Explore data oriented programming, contrast it with object oriented programming, and see how separating data from behavior enables predictable code in microservices exchanging json, protobuf, using records and pattern matching.
Explore algebraic data types by distinguishing product (end) types from sum (sealed) types, using address and customer records and choices like credit card or PayPal.
Introduce a sealed interface with credit card and PayPal records, demonstrate an exhaustive switch, and log payment processing in a Java data oriented demo using a main method.
Demonstrate a sealed contact type with email and phone records, and use pattern matching in a login verification service to send multi-factor authentication codes accordingly.
Explore the difference between enums and sealed types in Java, showing how enums restrict instances and sealed types restrict variants yet allow additional properties, guiding when to choose sealed types.
Explore data oriented programming principles: model data as data with immutable records and types, treat data as facts, validate at the boundary with compact constructors, and make illegal states unrepresentable.
Discover how data oriented programming uses small, immutable types to enforce domain rules and prevent misordered parameters, by modeling email and message as validated value types in a send service.
Show that records can have methods by demonstrating a derived full-name value method on an immutable record, while warning against methods with side effects that harm testability.
Explore data oriented programming: separate data as facts from behavior, model data with immutable algebraic data types, validate at the boundary to prevent illegal states and solve business problems.
Model domain concepts by designing data structures that reflect key business entities like customer, order, and product, define their relationships, states, transitions, and recurring patterns to produce expressive, auditable code.
Model state change in applications using sealed types and enums instead of booleans, linking state to specific fields like cancel reason or tracking number for cleaner, scalable lifecycles.
Model a loan application workflow in modern java, evaluating eligibility and setting interest rates for personal, auto, and property loans based on credit score, income, and loan terms.
Model a Java data domain with records for applicant, loan terms, and address. Build a sealed property hierarchy with residential and commercial types and a vehicle-based auto loan.
Model loan status with sealed interfaces and a loan processor that transitions from submitted to reviewed to approved or denied, using handle methods and credit score and annual income eligibility.
implement the loan processor to transition submitted loans to reviewed or denied by validating credit score and income for personal, auto, and property loans.
Determine loan interest rates by type: personal, auto (car or motorcycle by engine cc), and property (residential or commercial), then approve the loan and apply the computed rate.
Clarify why the loan status can contain the loan in a data oriented, domain driven design. Emphasize tracking state transitions as first class entities, enabling state-specific properties and workflow behavior.
Explore domain modeling in modern Java by designing data structures that represent business concepts, including simple values, choice types, and workflows modeling state transitions, illustrated by a loan application.
Explore modeling uncertainty with a sealed option type in Java, representing present or absent values; implement helpers, isPresent and orElse, and a demo showing a customer lookup.
Model an either type in Java by building a sealed interface with left and right cases, returning either a failure or success value and wrapping third-party phone or email types.
Learn how to handle more than two options by wrapping third-party types with a sealed interface and records to make an either type work.
Model errors with option and either types to represent missing data and failures, replacing Java's checked exceptions.
Model a file reader utility with a sealed interface and records for data present, file not found, and access denied, showcasing data oriented programming in input/output handling.
Implement a generic result type in Java to model success or failure via a sealed interface with records, including helper methods and pattern matching for file reading outcomes.
Demonstrate a generic result type for an http client response in a demo, building an external service client with a logger and returning a string via result.success or result.failure.
Explore when throwing exceptions helps or harms, noting verbose try-catch boilerplate, disrupted control flow, and potential state inconsistencies, and how sealed types or result/either models errors for clearer, exhaustive handling.
Explore polymorphic deserialization with Jackson to map json into sealed types like email or phone contacts. Use json subtypes and type information to preserve type safety in microservice communication.
Explore how Jackson uses JSON subtypes and JSON type info to deserialize abstract contact types into concrete email or phone objects, with a default fallback.
Learn how to implement polymorphic deserialization with Jackson by using a type field to map mixed info fields to email and phone types, including default handling when type is missing.
Use Jackson mixins to deserialize sealed domain types without invasive annotations, then create a mixin, register it with the object mapper, and enable correct deserialization of the domain type.
Leverage Jackson for polymorphic deserialization of JSON into Java types, automatically identifying subtypes from properties; use type information or a dummy class to host annotations and configure the mapper.
Develop an order processing system using Spring Boot to orchestrate payment processing, invoice generation, shipping, and fulfillment across microservices, with the order service as the entry point.
Explore external services through products, customers, payments, billing, and shipping APIs. Understand active, discontinued, and bundle products, and follow phase one happy-path API workflows.
Outline the order workflow from placed to fulfilled, detailing state transitions through validated, invoiced, and shipped, and cover pricing with tax, discounts, validation, payment, and shipping via external service APIs.
Explore a scalable order pipeline with a rest controller, an order service, and an order creation workflow orchestrator, using helper services for validation, pricing, payment, and shipping, enabling cancellation workflows.
Create a spring boot 4.0 maven project for java 25 web service, add validation and http client, and organize packages like client, config, controller, exception, model, orchestrator, service, and util.
Code with me as we quickly build models, records, and sealed types, exploring how the instructor tackles small decisions while learning new features with a dummy app.
Model domain data with Java records and sealed interfaces, defining product types (single, bundle) and statuses (active, discontinued), customer with address, and a payment workflow with processed or declined statuses.
Create and model invoice data structures, including a price summary with subtotal, discount, tax, and final amount, and implement paid and unpaid invoice requests with shipping details.
Validate customer id, product id, and quantity at rest controller. Generate an order id in the service and pass a create order command to the orchestrator, including the order request.
Implement a runtime application exception system with static factory methods for domain error and system error cases, including customer not found and product not found, using a generic type T.
Learn why we create a product client interface for a single implementation, guided by dependency inversion, to enable future-proofing and clear contracts for potential gRPC use.
Implement a product client using a Spring web client, base URL, and URI; extend an abstract service client that executes requests via suppliers and maps 404 to product not found.
Define and implement the customer client interface and service, including get customer by id and not found handling, then build a payment client to process payments via rest post calls.
Define and implement billing and shipping clients using a rest client, supporting create invoice (paid/unpaid) and schedule shipping requests, with an abstract service base and error handling.
Define and implement the request validator service to validate customer and product data (including product status), using product and customer clients, and build the order object for the orchestrator.
Create price calculator that builds a price summary from an order, computing subtotal, discount, tax by state, and final amount; supports single and bundle products with unit and discounted prices.
Consolidate the payment and billing into a single service that processes payments, generates invoices (paid or unpaid), and handles declined statuses for regular and business customers.
Implement a shipping service that builds a shipping request from the order, including the recipient and shipment items by product id and quantity, and schedules shipping using the shipping client.
Define and implement the order state machine for the orchestrator with a sealed order state interface and states such as placed, validated, invoiced, shipped, and fulfilled.
Define an order orchestrator to drive state transitions by routing each order state (placed, validated, invoiced, shipped, fulfilled) to handle methods, recursively orchestrating until fulfillment and throwing exceptions on failures.
Implement the order orchestrator with injected validator, price calculator, payment billing, and shipping services. Drive state transitions from placed to fulfilled through validated, price, invoice, and shipped states.
Explore why the shipped state should not be the final state, and how a dedicated fulfilled state accommodates future changes like a notify step.
Implement an order service that processes order requests into create order commands, uses a domain DTO mapper, orchestrates fulfillment, and maps results to an order response with invoices and shipments.
Design and implement a Spring REST controller for placing orders, wiring the order service via constructor, validating the order request with Jakarta annotations, and exposing a POST /orders endpoint.
Learn how to implement a controller advice to handle application exceptions and return a problem detail in a JSON format per RFC 7807 with type, title, status, detail, and instance.
This lecture explains building problem detail objects for application exceptions by mapping domain and system errors, such as entity not found, payment declined, and service unavailable, to appropriate HTTP statuses.
Expose spring beans in the config package and implement a logging interceptor for the client http requests, logging method, url, and body to aid debugging across five microservice clients.
Configure a Spring application by building an application configuration class that wires rest clients for product, customer, payment, billing, and shipping services, plus validator, price calculator, and order services.
Configure Jackson mixins to enable polymorphic deserialization for customers, products, and invoices, using JSON type info and id detection. Register mixins with the Spring Jackson annotation to the object mapper.
Prepare for the final demo by configuring service URLs in application.properties for product and customer client beans, ensure external services are up, then run the app and test with Postman.
Showcases testing of a running app with Jakarta validation, handling method argument not valid exceptions and problem detail responses, including not found, discontinued, and payment declined cases, plus happy path.
Design an order cancellation workflow orchestrator to handle state transitions from submission to validated, including validation checks within 30 days, return label initiation, refund, and item cancellation.
Prerequisite: Prior knowledge of Java (up to version 17)
--
Lets deep dive into Data Oriented Programming (DOP) in Java. A modern, practical, and forward-looking programming paradigm that is reshaping how Java applications are designed and developed.
In this masterclass, you will learn how to write clearer, safer, and more maintainable Java code by shifting your mindset from objects and inheritance to data and behavior separation. Through hands-on lessons and real-world use cases, you will discover how to leverage Java’s latest language features Records, Sealed Types, and Pattern Matching to build data-centric applications that are easy to reason about and evolve.
What You Will Learn
Crash Courses on Key Modern Java Features
Records: Learn how Java Records simplify data modeling, enforce immutability, and reduce boilerplate & when to choose records over classes.
Sealed Types: Master sealed classes and interfaces to build expressive, restricted hierarchies and eliminate misuse of inheritance.
Pattern Matching: Simplify conditionals using pattern matching with switch expressions, including nested and guarded patterns.
Foundations of Data Oriented Programming
Understand the principles of DOP and how it contrasts with traditional OOP.
Dive into Algebraic Data Types (ADTs) in Java using Records and Sealed Types to model domain logic precisely and safely.
Practical Use Cases and Real-World Integration
Implement DOP in real-world scenarios, from API modeling to complex business rules.
Serialize and deserialize sealed hierarchies using Jackson including how to work with polymorphic types in JSON.
Explore data modeling, validation logic, and how DOP can simplify state machines, complex business workflows.
Better Error Handling
Use sealed hierarchies to represent all possible error cases.
Apply pattern matching to handle errors in a concise and exhaustive way. No missed edge cases.
Hands-On Final Project
Why Take This Course?
This course is designed for Java developers who want to:
Stay ahead with modern Java features
Write more declarative, composable, and readable code
Replace legacy boilerplate with expressive data models
Understand the real value of Records, Sealed Types, and Pattern Matching beyond syntax
Learn data oriented thinking, ADTs, and functional ideas without leaving Java
Whether you are building APIs, business systems or modern backend services, this course will transform how you model, process, and reason about data in Java.