Domain Modeling Made Functional: A jump into the functional world
Tags: beginners, csharp, books, review
Published: 2022-02-07 14:18:26

_I originally published an extended version of this post on [my blog](https://canro91.github.io/2021/12/13/DomainModelingMadeFunctional/)._

Are you intrigued by functional programming? But you find it difficult because of all definitions and slang? Monads, monoids, endofunctors…This is a good starting point to jump into the functional world.

**"Domain modeling made functional" teaches to capture requirements, constraints, and business rules in a system using types.**

All the code samples are in F#. But, you can port the concepts from this book to your Object-Oriented language using built-in features or third-party libraries.

These are the two main lessons I learned from reading this book.

## 1. Express Domain Restrictions with Types

**Express restrictions in your design and enforce constraints with new types**.

In an order processing system, don't use integers to represent unit quantities in orders. A unit is a concept in the business domain. It should be in a separate class like `UnitQuantity`.

To restrict unit quantities between 1 and 1000, create a private constructor in the `UnitQuantity` type and only expose a factory method with the validation.

To enforce that an order should have at least one line item, create a `NonEmptyList` instead of a possibly empty `List`.

To represent optional values, don't use null values. Use an optional type, like `Option<T>`, similar to nullable primitive types in C#.

<figure>
<img src="https://source.unsplash.com/h_bYfwwOjXk/600x400" alt="Café customers in monochrome" />

<figcaption>Speaking of processing orders...Photo by <a href="https://unsplash.com/@alexjones?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Alex Jones</a> on <a href="https://unsplash.com/s/photos/ordering?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a></figcaption>
</figure>

## 2. Make errors part of your domain

**Follow the Signature Method Honesty principle by documenting all possible outputs of a method in its signature.**

For example, a `Divide` function shouldn't throw an exception. Instead write, `int Divide(int a, NonZeroInt b);`

Stay away from exceptions. Instead, use a `Result` type to wrap failed and successful values.

For example, a method to validate addresses should return `Result<CheckedAddress, AddressValidationError>`. It means either a valid address or a validation error.

```csharp
public Result<CheckedAddress, AddressValidationError>
    CheckAddressExists(UnvalidatedAddress address)
{
    //...
}

public class AddressValidationError {}
public class InvalidFormat : AddressValidationError {}
public class AddressNotFound : AddressValidationError {}
```

To work with exceptions in third-party code, wrap that code in a function that catches exceptions and returns a `Result`. Don't catch all exceptions, only those relevant to the domain. Like, timeouts or failed logins.

Voilà! These are the two main lessons I learned from this book. If you don't work with a functional language, you can still take advantage of the concepts of this book in your everyday programming. 

***

_Hey, there! I'm Cesar, a software engineer and lifelong learner. Visit my [Gumroad page](https://imcsarag.gumroad.com) to download my ebooks and check my courses._

_Happy coding!_