Domain Modelling

What makes you different from your competition

Created by Ed Blackburn / @ejblackburn

Why do I want to talk about this?

  • I think we have good developers, who solve non-trivial problems
  • I feel some simple concepts can make our code cleaner, easier to test, scale and more maintainable

Why model?

  • Domain models represent part of a business process
  • They include data (state) and business logic (behaviour)
  • Maintainability. Supporting intuitive code that reflects the problem domain is easier to comprehend, test, refactor, change and is heuristic, forcing the team to build domain knowledge?

Anaemic Model (Anti Pattern)

  • There is no behaviour. It's all CRUD
  • Primitive obsession
  • Mutable bags of data that contain little or no behaviour
  • Impossible to enforce business logic because state can be manipulated outside of intended use
  • Business logic in "Services"
  • Write only code
  • Feature Envy anti-pattern


  • Why is this mutable?
  • Why are they strings, do horses have legs, or strings?

public class Horse {
	public string Leg1 { get; set; }
	public string Leg2 { get; set; }
	public string Leg3 { get; set; }
	public string Leg4 { get; set; }


public class MoveHorse {
	public Gallop(Horse horse, int steps) {
		for(step = 0;step > steps;step++) {
			horse.Leg1 = "Move Fast";
			horse.Leg2 = "Move Fast";
			horse.Leg1 = "Put on ground";
			horse.Leg2 = "Put on Ground";
			horse.Leg3 = "Move Fast";
			horse.Leg4 = "Move Fast";

	public Cantor(Horse horse, int steps) {
		for(step = 0;step > steps;step++) {
			horse.Leg1 = "Move slow";
			horse.Leg1 = "Put on ground";
			horse.Leg2 = "Move slow";
			horse.Leg2 = "Put on ground";
			horse.Leg3 = "Move slow";
			horse.Leg3 = "Put on ground";
			horse.Leg4 = "Move slow";
			horse.Leg4 = "Put on ground";


The algorithm is wrong. This can get complicated quickly and is not intuitive.

Rich Model

  • Put behaviour and state together
  • Tell don't ask
  • Do not expose internals. Do not expose data structures
  • There is not such thing as a string!
  • Equality v Equivalence

An alternative:

  • No primitives
  • State encapsulated

class Horse {
	private Leg leg1;
	private Leg leg2;
	private Leg leg3;
	private Leg leg4;
	void Gallop() {..}
	void Cantor() {..}

Different types of object in a model

  • Value Object
  • Entity
  • It's all about the identity
  • Service layer

Value Objects

Immutable types. Enforce invariants: a name is not a string. A name can not be null or empty, can not begin or end with white space.

class Name {
	ctor(string name) {
		throw if null
		name = name.trim()
		throw if empty
	Equals(Name) {..}

Money Example

class Money {
	ctor(double value, Currency currency){..}

	Equals(Money other){
		return other.value == this.value && other.currency == this.currency;

var five_pounds = new Money(5, new GBP());
var ten_pounds = new Money(10, new GBP());

class Note {
	ctor(SerialNumber serial_number){..}

	Equals(Note other){
		return other.serial_number == this.serial_number;

Something closer to home

Represent two different things. Both use Guids..

class AccountId {
	ctor(string id){..}

class AuthToken {
	ctor(string id){..}
  • Can't accidental confuse them
  • What happens if we want to change the data-type or how it's formed? I.e. sequential guid for more db efficient guids? Or guids formed differently for sharding?


  • Defined by identity
  • Here lives behaviour!
  • ..a category of objects which seem to have an identity, which remains the same throughout the states of the software. For these objects it is not the attributes which matter, but a thread of continuity and identity, which spans the life of a system and can extend beyond it. Such objects are called Entities

    - Eric Evans


class Product {
	private ProductId;

		return Product.ProductId == this.ProductId;



  • An encapsulated graph of domain objects
  • Only accessible via the root object
  • Remember do not expose data structures

Further concepts

  • Hypermedia APIs
  • CQRS
  • Repository Pattern
  • Document databases
  • Bounded Contexts
  • Ubiquitous language

Enterprise Bullshit?