Skip to content

Commit

Permalink
functional type system docs enhanced
Browse files Browse the repository at this point in the history
  • Loading branch information
bslota committed May 24, 2019
1 parent 0968a2a commit df4b9c8
Showing 1 changed file with 19 additions and 1 deletion.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -320,7 +320,7 @@ Each class that represents a business concept is immutable, thanks to which we:
* control all side effects much clearer.

#### Pure functions
Modelling domain operations, discovered in Design Level Event Storming, as pure functions, and declaring them in
We model domain operations, discovered in Design Level Event Storming, as pure functions, and declare them in
both domain and application layers in the form of Java's functional interfaces. Their implementations are placed
in infrastructure layer as ordinary methods with side effects. Thanks to this approach we can follow the abstraction
of ubiquitous language explicitly, and keep this abstraction implementation-agnostic. As an example, you could have
Expand Down Expand Up @@ -384,6 +384,24 @@ public Either<BookHoldFailed, BookPlacedOnHoldEvents> placeOnHold(AvailableBook
```
The more errors we discover at compile time the better.
Yet another advantage of applying such type system is that we can represent business flows and state transitions
with functions much easier. As an example, following functions:
```
placeOnHold: AvailableBook -> BookHoldFailed | BookPlacedOnHold
cancelHold: BookOnHold -> BookHoldCancelingFailed | BookHoldCanceled
```
are much more concise and descriptive than these:
```
placeOnHold: Book -> BookHoldFailed | BookPlacedOnHold
cancelHold: Book -> BookHoldCancelingFailed | BookHoldCanceled
```
as here we have a lot of constraints hidden within function implementations.
Moreover if you think of your domain as a set of operations (functions) that are being executed on business objects
(aggregates) you don't think of any execution model (like async processing). It is fine, because you don't have to.
Domain functions are free from I/O operations, async, and other side-effects-prone things, which are put into the
infrastructure layer. Thanks to this, we can easily test them without mocking mentioned parts.
#### Monads
Business methods might have different results. One might return a value or a `null`, throw an exception when something
unexpected happens or just return different objects under different circumstances. All those situations are typical
Expand Down

0 comments on commit df4b9c8

Please sign in to comment.