University of Oxford Logo University of OxfordSoftware Engineering - Home
On Facebook
Follow us on twitter
Linked in
Linked in
Google plus
Google plus
Stumble Upon
Stumble Upon

Domain-Driven Design

Domain-Driven Design ("DDD") is a software design approach that focuses on the domain of the system rather than technology. There is an emphasis on building a shared mental model and representing that domain model in code in the simplest way possible. Technical details such as database storage, frameworks, etc., are considered to be secondary aspects of the design. The module will focus on DDD and design in general and related topics, such as documentation and some aspects of software architecture. This course uses basic functional programming concepts to express the domain and design: types as documentation, and functions (and composition of functions) for implementation. Object-oriented equivalents and OO design patterns may also be introduced when appropriate.


This course will run once a year.

Course dates

21st October 2024Oxford University Department of Computer Science - Held in the Department02 places remaining.


On completing the class, attendees will:

  • Understand the principles of domain-driven design and how it differs from object-oriented design, database-driven design, etc.
  • Understand when and why to use DDD instead of other approaches.
  • Know how to interview domain experts to understand the key concepts and activities in a domain, with a strong emphasis on communication and developing shared mental models.
  • Know how to document these concepts and activities using algebraic types and functions
  • Know how to use types to capture as many details of the domain as possible, and how to "make illegal states unrepresentable" and reduce the need for unit tests.
  • Know the principles of composition, applied to both functions and types, and how to compose an activity (modelled as a function) from smaller functions.
  • Understand how to apply the DDD approach to error handling.
  • Understand how to integrate non-pure elements into the design (I/O, databases, etc) and manage state within an application.
  • Understand the DDD approach to partitioning a design ("bounded contexts") and how a design might relate to software architecture.


Understanding a domain:
the software development process; requirements, analysis, design; communication and feedback; use-cases, stories, workflows
Modelling a domain:
algebraic types and function types; inheritance, interfaces; request/response vs. input/output
Refining the domain:
using types to capture constraints; optional and sum types; identity, entities, value objects; refactoring
Modelling state and time:
state machines; invariants; commands and events; event sourcing; temporal interactions
Designing for errors:
total functions; “honest” function signatures; domain errors; modelling and composing error-generating functions; validation
Purity, I/O , and testing:
database-centric vs. domain-centric architectures; stateful vs. stateless designs; determinacy and unit testing; moving IO to the edge; error recovery, transactions, compensation; immutable data, ledgers
Domain-driven designs and databases:
persistence to database or document-store; command-query separation; storing state machines in databases; snapshot storage, temporal databases, event sourcing; reporting
Partitioning and architecting a domain-driven design:
bounded contexts; context maps, the “reverse Conway manoeuvre”; public domain events vs. internal events; serializing domain objects; deployment (modular monolith, SOA/microservices, serverless)
Putting it all together:
review of all techniques; building a complete app, including requirements gathering, design, implementation, error handling, and database storage

Assessment criteria

The assignment is intended to determine, in order of decreasing importance:

  • Have you understood the key principles of domain driven design? Can you explain how DDD is different from other software design approaches?
  • Have you demonstrated how to represent a domain using algebraic types that can be understood by non-technical domain experts and other stakeholders?
  • Do you understand how to avoid primitives and how to represent simple constrained types, optional data, etc? Can you show how to refine a design to eliminate certain kinds of errors and the need for defensive programming?
  • Do you understand the DDD approach to state management and databases?
  • Do you understand to partition a design and plan an architecture around this?


The course will require basic programming skills, such as use of an editor, use of git, etc. No prior knowledge of DDD or functional programming is required - all concepts will be introduced as needed within the course. It is not intended to cover functional programming in any depth; it is independent of but complementary to FPR.

The programming language used in this course is F#, as it supports both object-oriented and functional styles of programming. No prior experience of F# is needed.