SlideShare a Scribd company logo
Functional
Domain Driven Design
disclaimer: is still a “work in progress”
Focus on the domain and
domain logic rather than
technology
(Eric Evans)
Why not with a functional approach?
A monad is a triple (T, η, μ) where T is an
endofunctor T: X->X and η: I->T and μ: T x T-
>T are 2 natural transformations satisfying these
laws:
• Identity law: μ(η(T)) = T = μ(T(η))
• Associative law: μ(μ(T × T) × T)) = μ(T ×
μ(T × T))
A monad in X is just a monoid in the
category of endofunctors of X, with product
× replaced by composition of endofunctors
and unit set by the identity endofunctor
What is a monad?
software developer @ codiceplastico
@amelchiori
alessandro@codiceplastico.com
About me
F#: a gentle introduction
let myString = "original value"
let myString = "new value”
Immutability: values, not variables!
Duplicate definition of value ‘myString’
let add x y = x + y
add 2 2
x:int -> y:int -> int
Type inference
void ProcessItems(Item[] items, Action<Item> action)
{
for(int i = 0; i < items.Length; i++)
{
var item = items[i];
action(item);
}
}
Recursion
let rec processItems action = function
| [] -> ()
| head :: tail ->
action head;
processItems tail
Recursion
let add x y = x + y
x:int -> y:int -> int
Partial function application
let add5 x = add 5
x:int -> int
let value = add5 10
(value = 15)
let f x = x * x
x:int -> int
let g x = -x/2 + 5
x:int -> int
Functions composition
let (<<) f g x = f (g x)
('b -> 'c) -> ('a -> 'b) -> 'a -> ’c
let h x = f << g
x:int -> int
let square x = x * x
let add x y = x + y
let toString x = x.ToString()
let complexFunction x = toString (add 5 (square x))
Pipeline operator
let (|>) x f = f x
let complexFunction x = x |> square |> add 5 |> toString
let div x y = x / y
x:int -> y:int -> int
div 10 5 // 2
div 10 0 // System.DivideByZeroException
Option type
let safeDiv x y =
if y = 0 then None
else Some(x/y)
x:int -> y:int -> int option
let safeDiv x y =
match y with
| 0 -> None
| _ -> Some(x/y)
Pattern matching
let safeDiv x y =
match y with
| 0 -> None
| 1 -> Some(x/y)
Incomplete pattern matches on this expression.
For example, the value '2' may indicate a case not covered
by the pattern(s)
type State =
| On
| Off
let x = On
let y = Off
Discriminated unions
let div (x, y) = …
(int * int) - > int
Tuples
let div (x, y) =
match (x, y) with
| (_, 0) -> None
| (_, _) -> Some(x/ y)
type site = { Title : string; Url : string }
Records
let homepage =
{ Title = "Google"; Url = "http://www.google.com" }
let next = { homepage with Title = "NextPage" }
OK! Let’s go…
public class Company
{
public String BusinessName { get; set; }
public String TaxCode { get; set; }
public String VatNumber { get; set; }
public String AssignedBank { get; set; }
public Boolean IsBankAuthorized { get; set; }
}
Value object
An immutable object, like money or a date
range, whose equality isn't based on identity
(in general equality is based on all fields
equality)
Martin Fowler
Value object
An immutable object, like money or a date
range, whose equality isn't based on identity
(in general equality is based on all fields
equality)
Martin Fowler
public class CompanyProfile
{
public String BusinessName { get; private set; }
public String TaxCode { get; private set; }
public String VatNumber { get; private set; }
public CompanyProfile(String businessName, String taxCode,
String vatNumber=null)
{
// check if parameters are valid
BusinessName = businessName;
TaxCode = taxCode;
VatNumber = vatNumber;
}
}
Value object
public class CompanyProfile
{
// same as before…
public override Boolean Equals(Object other)
{
var target = other as CompanyProfile;
return target == null ? false :
target.BusinessName == this.BusinessName
&& target.TaxCode == this.TaxCode
&& target.VatCode == this.VatCode;
}
public override Int32 GetHashCode()
{
// ...
}
}
Value object’s equality
type CompanyProfile = {
BusinessName : string;
TaxCode : string;
VatNumber : string
}
Value object in F#
option;
let profile = {
BusinessName = “CodicePlastico”;
TaxNumber = “1234567890”;
}
Ubiquitous Language is the concept of
defining a language (spoken and written)
that is equally used across developers and
domain experts
Ubiquitous language
public class Company
{
...
public String AssignedBank { get; set; }
public Boolean IsBankAuthorized { get; set; }
}
Ubiquitous language
Rule 1:
A company must have a bank to work with
Rule 2:
A company can be authorized to work with its
assigned bank
Rule 3:
A company can be not authorized to work with
its assigned bank
Business logic
Make illegal states unrepresentable
Ubiquitous language
type Bank = Bank of string
type UnauthorizedBank = UnauthorizedBank of Bank
type AuthorizedBank = AuthorizedBank of Bank
type AssignedBank =
| Unauthorized of UnauthorizedBank
| Authorized of AuthorizedBank
Business logic in F#
type CompanyProfile = {
BusinessName: string,
TaxCode: string,
VatCode: string option
}
type Bank = Bank of string
type UnauthorizedBank =
UnauthorizedBank of Bank
type AuthorizedBank =
AuthorizedBank of Bank
type AssignedBank =
| Unauthorized of UnauthorizedBank
| Authorized of AuthorizedBank
type Company = {
Profile: CompanyProfile,
Bank: AssignedBank
}
Ubiquitous language to the rescue
The central idea of specification is to
separate the statement of how to match
a candidate, from the candidate object
that it is matched against
Specification
type SpecificationResult =
| Success
| Failure of string
type Spec<'a> = 'a -> SpecificationResult
Specification
type Category =
| Default
| Premium
| Gold
type Customer = {
Name: string;
Category: Category;
}
Specification: our (simple) domain
type Item = {
Code: string;
Quantity: int;
}
type Order = {
Number: string;
Customer: Customer;
Items: Item list;
}
let isOrderFullFilled : Spec<Order> =
let p order =
match Seq.isEmpty order.Items with
| true -> Failure("Items' list empty")
| false -> Success
in p
let isGoldCustomer : Spec<Customer> =
let p customer =
match customer.Category with
| Gold -> Success
| _ -> Failure("No-gold customer")
in p
Specification
let And (left: Spec<'a>) (right: Spec<'a>) : Spec<'a> =
let p entity =
match left entity with
| Success -> right entity
| _ -> Failure("And specification is not satisfied")
in p
Specification
let order = {
Number = "1234";
Customer = { Name = "Alessandro"; Category = Gold};
Items = [
{ Code = "Code1"; Quantity = 1};
{ Code = "Code2"; Quantity = 2};
];
}
let isOrderValid = And
isOrderFullFilled
(adapt isGoldCustomer (fun order -> order.Customer))
let isValid = isOrderValid order
Specification
CQRS & Event Sourcing
A single model cannot be appropriate
for reporting, searching and
transactional behavior
Greg Young
CQRS
State transition are an important part of our
problem space and should be modeled
within our domain
Greg Young
Event Sourcing
public void AddItemToCart(Item item)
{
// validation
if (item == null)
throw new ArgumentNullException();
// execution
_items.Add(item.Id);
}
Commands, events and…fold (step 1)
public void AddItemToCart(Item item)
{
if (item == null)
throw new ArgumentNullException();
var domainEvent = new ItemAddedToCart
{ CartId = this.Id, ItemId = item.Id };
Apply(domainEvent)
}
private void Apply(ItemAddedToCart domainEvent)
{
_items.Add(domainEvent.ItemId);
}
Commands, events and…fold (step 2)
public void AddItemToCart(Item item)
{
if (item == null)
throw new ArgumentNullException();
var domainEvent = new ItemAddedToCart
{ CartId = this.Id, ItemId = item.Id };
Apply(this, domainEvent)
}
private void Apply(Cart target, ItemAddedToCart domainEvent)
{
target._items.Add(domainEvent.ItemId);
}
Commands, events and…fold (step 3)
public static Cart Apply(Cart target, CartCreated domainEvent)
{
return new Cart { Id = domainEvent.CartId, _items = new String[0] };
}
public static Cart Apply(Cart target, ItemAddedToCart domainEvent)
{
var items = target._items.ToList();
items.Add(domainEvent.ItemId);
return new Cart { Id = domainEvent.CartId, _items = items };
}
public static Cart Apply(Cart target, ItemRemovedFromCart domainEvent)
{
var items = target._items.ToList();
items.Remove(domainEvent.ItemId);
return new Cart { Id = domainEvent.CartId, _items = items };
}
Commands, events and…fold (step 4)
Cart.Apply(null, new CartCreated { CartId=1 })
Commands, events and…fold (step 5)
Cart.Apply(
Cart.Apply(null, new CartCreated { CartId=1}),
new ItemAddedToCart { CartId = 1, ItemId = "A"
}
)
Commands, events and…fold (step 5)
Cart.Apply(
Cart.Apply(
Cart.Apply(null, new CartCreated { CartId=1}),
new ItemAddedToCart { CartId = 1, ItemId = "A"
}
),
new ItemAddedToCart { CartId = 1, ItemId = "B" }
)
Commands, events and…fold (step 5)
Cart.Apply(
Cart.Apply(
Cart.Apply(
Cart.Apply(null, new CartCreated { CartId=1}),
new ItemAddedToCart { CartId = 1, ItemId = "A"
}
),
new ItemAddedToCart { CartId = 1, ItemId = "B" }
),
new ItemRemovedFromCart { CartId = 1, ItemId = "A" }
)
Commands, events and…fold (step 5)
Executing a command:
type Exec =
( CartState * Command ) -> DomainEvent
Applying an event:
type Apply =
( CartState * DomainEvent ) -> CartState
Commands, events and…fold (step 6)
type Command =
| Create of string
| AddItem of int
| RemoveItem of int
| RemoveAllItems
| Checkout
type Event =
| Created of string
| ItemAdded of int
| ItemRemoved of
int
| AllItemsRemoved
| Checkedout
Commands, events and…fold (step 7)
type CartState = {
Name: string;
Items: List<int>;
Active: bool;
}
let apply state = function
| Created x -> { Cart.empty with Name = x }
| ItemAdded x -> { state with Items = List.append state.Items [x] }
| ItemRemoved x ->
{ state with Items = List.filter (fun i -> i <> x ) state.Items }
| Removed _ -> { state with Items = List.empty }
| Checkedout _ -> { state with Active = false }
Commands, events and…fold (step 8)
let domainEvents = [
Created("cart1");
ItemAdded(1);
ItemAdded(2);
Removed;
ItemAdded(3);
Checkedout;
]
let state = List.fold apply Cart.empty domainEvents
Commands, events and…fold (step 9)
Tackling Complexity in the
Heart of Software
Eric Evans
…but, when DDD?
Functional DDD

More Related Content

What's hot

The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30
Mahmoud Samir Fayed
 
The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84
Mahmoud Samir Fayed
 
Oops lab manual2
Oops lab manual2Oops lab manual2
Oops lab manual2
Mouna Guru
 
The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189
Mahmoud Samir Fayed
 
The Ring programming language version 1.2 book - Part 20 of 84
The Ring programming language version 1.2 book - Part 20 of 84The Ring programming language version 1.2 book - Part 20 of 84
The Ring programming language version 1.2 book - Part 20 of 84
Mahmoud Samir Fayed
 
DIWE - Working with MySQL Databases
DIWE - Working with MySQL DatabasesDIWE - Working with MySQL Databases
DIWE - Working with MySQL Databases
Rasan Samarasinghe
 
The Ring programming language version 1.5 book - Part 6 of 31
The Ring programming language version 1.5 book - Part 6 of 31The Ring programming language version 1.5 book - Part 6 of 31
The Ring programming language version 1.5 book - Part 6 of 31
Mahmoud Samir Fayed
 
Collection v3
Collection v3Collection v3
Collection v3
Sunil OS
 
Java cheatsheet
Java cheatsheetJava cheatsheet
Java cheatsheet
Anass SABANI
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210
Mahmoud Samir Fayed
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
oxbow_lakes
 
Scalaz
ScalazScalaz
Scalaz
mpilquist
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
Srikanth Shreenivas
 
Evolutionary Problems In Aspect Oriented Software Development
Evolutionary Problems In Aspect Oriented Software DevelopmentEvolutionary Problems In Aspect Oriented Software Development
Evolutionary Problems In Aspect Oriented Software Development
kim.mens
 
API design: using type classes and dependent types
API design: using type classes and dependent typesAPI design: using type classes and dependent types
API design: using type classes and dependent types
bmlever
 
The Technical Debt of Programming Languages
The Technical Debt of Programming LanguagesThe Technical Debt of Programming Languages
The Technical Debt of Programming Languages
Hernan Wilkinson
 
C++ Expression Templateを使って式をコンパイル時に微分
C++ Expression Templateを使って式をコンパイル時に微分C++ Expression Templateを使って式をコンパイル時に微分
C++ Expression Templateを使って式をコンパイル時に微分
masahiro nishiba
 
The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180
Mahmoud Samir Fayed
 

What's hot (20)

informatics practices practical file
informatics practices practical fileinformatics practices practical file
informatics practices practical file
 
The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30The Ring programming language version 1.4 book - Part 9 of 30
The Ring programming language version 1.4 book - Part 9 of 30
 
The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84The Ring programming language version 1.2 book - Part 22 of 84
The Ring programming language version 1.2 book - Part 22 of 84
 
Oops lab manual2
Oops lab manual2Oops lab manual2
Oops lab manual2
 
The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189The Ring programming language version 1.6 book - Part 35 of 189
The Ring programming language version 1.6 book - Part 35 of 189
 
The Ring programming language version 1.2 book - Part 20 of 84
The Ring programming language version 1.2 book - Part 20 of 84The Ring programming language version 1.2 book - Part 20 of 84
The Ring programming language version 1.2 book - Part 20 of 84
 
DIWE - Working with MySQL Databases
DIWE - Working with MySQL DatabasesDIWE - Working with MySQL Databases
DIWE - Working with MySQL Databases
 
The Ring programming language version 1.5 book - Part 6 of 31
The Ring programming language version 1.5 book - Part 6 of 31The Ring programming language version 1.5 book - Part 6 of 31
The Ring programming language version 1.5 book - Part 6 of 31
 
Collection v3
Collection v3Collection v3
Collection v3
 
Property Based Testing
Property Based TestingProperty Based Testing
Property Based Testing
 
Java cheatsheet
Java cheatsheetJava cheatsheet
Java cheatsheet
 
The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210The Ring programming language version 1.9 book - Part 41 of 210
The Ring programming language version 1.9 book - Part 41 of 210
 
Practical scalaz
Practical scalazPractical scalaz
Practical scalaz
 
Scalaz
ScalazScalaz
Scalaz
 
Practices For Becoming A Better Programmer
Practices For Becoming A Better ProgrammerPractices For Becoming A Better Programmer
Practices For Becoming A Better Programmer
 
Evolutionary Problems In Aspect Oriented Software Development
Evolutionary Problems In Aspect Oriented Software DevelopmentEvolutionary Problems In Aspect Oriented Software Development
Evolutionary Problems In Aspect Oriented Software Development
 
API design: using type classes and dependent types
API design: using type classes and dependent typesAPI design: using type classes and dependent types
API design: using type classes and dependent types
 
The Technical Debt of Programming Languages
The Technical Debt of Programming LanguagesThe Technical Debt of Programming Languages
The Technical Debt of Programming Languages
 
C++ Expression Templateを使って式をコンパイル時に微分
C++ Expression Templateを使って式をコンパイル時に微分C++ Expression Templateを使って式をコンパイル時に微分
C++ Expression Templateを使って式をコンパイル時に微分
 
The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180The Ring programming language version 1.5.1 book - Part 29 of 180
The Ring programming language version 1.5.1 book - Part 29 of 180
 

Similar to Functional DDD

Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
Scott Wlaschin
 
Improving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con BerlinImproving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con Berlin
Iain Hull
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
Tomer Gabel
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
Tikal Knowledge
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
진성 오
 
Types and Immutability: why you should care
Types and Immutability: why you should careTypes and Immutability: why you should care
Types and Immutability: why you should care
Jean Carlo Emer
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
Juan Pablo
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meetMario Fusco
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1saydin_soft
 
Types in JavaScript: why you should care
Types in JavaScript: why you should careTypes in JavaScript: why you should care
Types in JavaScript: why you should care
Jean Carlo Emer
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
Richard Fox
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
Prashant Kalkar
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
Iain Hull
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
Knoldus Inc.
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
Kaz Yoshikawa
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
Eugene Zharkov
 
Demystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with ShapelessDemystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with Shapeless
Yurii Ostapchuk
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
Javier Eguiluz
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
Arthur Xavier
 
Arrays
ArraysArrays

Similar to Functional DDD (20)

Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)Functional Programming Patterns (BuildStuff '14)
Functional Programming Patterns (BuildStuff '14)
 
Improving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con BerlinImproving Correctness With Type - Goto Con Berlin
Improving Correctness With Type - Goto Con Berlin
 
Scala Back to Basics: Type Classes
Scala Back to Basics: Type ClassesScala Back to Basics: Type Classes
Scala Back to Basics: Type Classes
 
JBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java ProgrammersJBUG 11 - Scala For Java Programmers
JBUG 11 - Scala For Java Programmers
 
Swift 함수 커링 사용하기
Swift 함수 커링 사용하기Swift 함수 커링 사용하기
Swift 함수 커링 사용하기
 
Types and Immutability: why you should care
Types and Immutability: why you should careTypes and Immutability: why you should care
Types and Immutability: why you should care
 
Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#Lo Mejor Del Pdc2008 El Futrode C#
Lo Mejor Del Pdc2008 El Futrode C#
 
Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
 
Types in JavaScript: why you should care
Types in JavaScript: why you should careTypes in JavaScript: why you should care
Types in JavaScript: why you should care
 
Generics and Inference
Generics and InferenceGenerics and Inference
Generics and Inference
 
Functional programming ii
Functional programming iiFunctional programming ii
Functional programming ii
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
 
Functions In Scala
Functions In Scala Functions In Scala
Functions In Scala
 
Idioms in swift 2016 05c
Idioms in swift 2016 05cIdioms in swift 2016 05c
Idioms in swift 2016 05c
 
Elm: give it a try
Elm: give it a tryElm: give it a try
Elm: give it a try
 
Demystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with ShapelessDemystifying Type Class derivation with Shapeless
Demystifying Type Class derivation with Shapeless
 
Twig tips and tricks
Twig tips and tricksTwig tips and tricks
Twig tips and tricks
 
PureScript & Pux
PureScript & PuxPureScript & Pux
PureScript & Pux
 
Arrays
ArraysArrays
Arrays
 

More from Alessandro Melchiori

Scale your (aks) cluster, luke!
Scale your (aks) cluster, luke!Scale your (aks) cluster, luke!
Scale your (aks) cluster, luke!
Alessandro Melchiori
 
A quick introduction to AKS
A quick introduction to AKSA quick introduction to AKS
A quick introduction to AKS
Alessandro Melchiori
 
Developing reliable applications with .net core and AKS
Developing reliable applications with .net core and AKSDeveloping reliable applications with .net core and AKS
Developing reliable applications with .net core and AKS
Alessandro Melchiori
 
VS Code tools for docker
VS Code tools for dockerVS Code tools for docker
VS Code tools for docker
Alessandro Melchiori
 
Developing reliable applications with .net core and AKS
Developing reliable applications with .net core and AKSDeveloping reliable applications with .net core and AKS
Developing reliable applications with .net core and AKS
Alessandro Melchiori
 
How to search...better! (azure search)
How to search...better! (azure search)How to search...better! (azure search)
How to search...better! (azure search)
Alessandro Melchiori
 
AKS: k8s e azure
AKS: k8s e azureAKS: k8s e azure
AKS: k8s e azure
Alessandro Melchiori
 
How to search...better!
How to search...better!How to search...better!
How to search...better!
Alessandro Melchiori
 
A quick tour around Azure Dev Spaces
A quick tour around Azure Dev SpacesA quick tour around Azure Dev Spaces
A quick tour around Azure Dev Spaces
Alessandro Melchiori
 
Azure functions: from a function to a whole application in 60 minutes
Azure functions: from a function to a whole application in 60 minutesAzure functions: from a function to a whole application in 60 minutes
Azure functions: from a function to a whole application in 60 minutes
Alessandro Melchiori
 
Aks: k8s e azure
Aks:  k8s e azureAks:  k8s e azure
Aks: k8s e azure
Alessandro Melchiori
 
Monitoring docker: from zero to Azure
Monitoring docker: from zero to AzureMonitoring docker: from zero to Azure
Monitoring docker: from zero to Azure
Alessandro Melchiori
 
Cooking Akka.net and Azure Service Fabric together
Cooking Akka.net and Azure Service Fabric togetherCooking Akka.net and Azure Service Fabric together
Cooking Akka.net and Azure Service Fabric together
Alessandro Melchiori
 
Azure data platform overview
Azure data platform overviewAzure data platform overview
Azure data platform overview
Alessandro Melchiori
 
ACR + ACS + VSTS: a complete ALM pipeline with docker and azure
ACR + ACS + VSTS: a complete ALM pipeline with docker and azureACR + ACS + VSTS: a complete ALM pipeline with docker and azure
ACR + ACS + VSTS: a complete ALM pipeline with docker and azure
Alessandro Melchiori
 
Docker & Azure
Docker & AzureDocker & Azure
Docker & Azure
Alessandro Melchiori
 
Docker and Azure
Docker and AzureDocker and Azure
Docker and Azure
Alessandro Melchiori
 
Come ti "pusho" il web con WebSockets: da 0 a SignalR
Come ti "pusho" il web con WebSockets: da 0 a SignalR Come ti "pusho" il web con WebSockets: da 0 a SignalR
Come ti "pusho" il web con WebSockets: da 0 a SignalR
Alessandro Melchiori
 
Docker &amp; azure
Docker &amp; azureDocker &amp; azure
Docker &amp; azure
Alessandro Melchiori
 
Azure service fabric: a gentle introduction
Azure service fabric: a gentle introductionAzure service fabric: a gentle introduction
Azure service fabric: a gentle introduction
Alessandro Melchiori
 

More from Alessandro Melchiori (20)

Scale your (aks) cluster, luke!
Scale your (aks) cluster, luke!Scale your (aks) cluster, luke!
Scale your (aks) cluster, luke!
 
A quick introduction to AKS
A quick introduction to AKSA quick introduction to AKS
A quick introduction to AKS
 
Developing reliable applications with .net core and AKS
Developing reliable applications with .net core and AKSDeveloping reliable applications with .net core and AKS
Developing reliable applications with .net core and AKS
 
VS Code tools for docker
VS Code tools for dockerVS Code tools for docker
VS Code tools for docker
 
Developing reliable applications with .net core and AKS
Developing reliable applications with .net core and AKSDeveloping reliable applications with .net core and AKS
Developing reliable applications with .net core and AKS
 
How to search...better! (azure search)
How to search...better! (azure search)How to search...better! (azure search)
How to search...better! (azure search)
 
AKS: k8s e azure
AKS: k8s e azureAKS: k8s e azure
AKS: k8s e azure
 
How to search...better!
How to search...better!How to search...better!
How to search...better!
 
A quick tour around Azure Dev Spaces
A quick tour around Azure Dev SpacesA quick tour around Azure Dev Spaces
A quick tour around Azure Dev Spaces
 
Azure functions: from a function to a whole application in 60 minutes
Azure functions: from a function to a whole application in 60 minutesAzure functions: from a function to a whole application in 60 minutes
Azure functions: from a function to a whole application in 60 minutes
 
Aks: k8s e azure
Aks:  k8s e azureAks:  k8s e azure
Aks: k8s e azure
 
Monitoring docker: from zero to Azure
Monitoring docker: from zero to AzureMonitoring docker: from zero to Azure
Monitoring docker: from zero to Azure
 
Cooking Akka.net and Azure Service Fabric together
Cooking Akka.net and Azure Service Fabric togetherCooking Akka.net and Azure Service Fabric together
Cooking Akka.net and Azure Service Fabric together
 
Azure data platform overview
Azure data platform overviewAzure data platform overview
Azure data platform overview
 
ACR + ACS + VSTS: a complete ALM pipeline with docker and azure
ACR + ACS + VSTS: a complete ALM pipeline with docker and azureACR + ACS + VSTS: a complete ALM pipeline with docker and azure
ACR + ACS + VSTS: a complete ALM pipeline with docker and azure
 
Docker & Azure
Docker & AzureDocker & Azure
Docker & Azure
 
Docker and Azure
Docker and AzureDocker and Azure
Docker and Azure
 
Come ti "pusho" il web con WebSockets: da 0 a SignalR
Come ti "pusho" il web con WebSockets: da 0 a SignalR Come ti "pusho" il web con WebSockets: da 0 a SignalR
Come ti "pusho" il web con WebSockets: da 0 a SignalR
 
Docker &amp; azure
Docker &amp; azureDocker &amp; azure
Docker &amp; azure
 
Azure service fabric: a gentle introduction
Azure service fabric: a gentle introductionAzure service fabric: a gentle introduction
Azure service fabric: a gentle introduction
 

Recently uploaded

Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Jay Das
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
kalichargn70th171
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Globus
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
vrstrong314
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
Philip Schwarz
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
rickgrimesss22
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Anthony Dahanne
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
Donna Lenk
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
Globus
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Mind IT Systems
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
Ortus Solutions, Corp
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
Juraj Vysvader
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
Georgi Kodinov
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
Globus
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
NYGGS Automation Suite
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
Tier1 app
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
Globus
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
takuyayamamoto1800
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus
 

Recently uploaded (20)

Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdfEnhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
Enhancing Project Management Efficiency_ Leveraging AI Tools like ChatGPT.pdf
 
Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024Globus Compute wth IRI Workflows - GlobusWorld 2024
Globus Compute wth IRI Workflows - GlobusWorld 2024
 
A Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdfA Comprehensive Look at Generative AI in Retail App Testing.pdf
A Comprehensive Look at Generative AI in Retail App Testing.pdf
 
Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...Developing Distributed High-performance Computing Capabilities of an Open Sci...
Developing Distributed High-performance Computing Capabilities of an Open Sci...
 
top nidhi software solution freedownload
top nidhi software solution freedownloadtop nidhi software solution freedownload
top nidhi software solution freedownload
 
A Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of PassageA Sighting of filterA in Typelevel Rite of Passage
A Sighting of filterA in Typelevel Rite of Passage
 
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptxTop Features to Include in Your Winzo Clone App for Business Growth (4).pptx
Top Features to Include in Your Winzo Clone App for Business Growth (4).pptx
 
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
Paketo Buildpacks : la meilleure façon de construire des images OCI? DevopsDa...
 
Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"Navigating the Metaverse: A Journey into Virtual Evolution"
Navigating the Metaverse: A Journey into Virtual Evolution"
 
Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024Globus Compute Introduction - GlobusWorld 2024
Globus Compute Introduction - GlobusWorld 2024
 
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
Custom Healthcare Software for Managing Chronic Conditions and Remote Patient...
 
Into the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdfInto the Box 2024 - Keynote Day 2 Slides.pdf
Into the Box 2024 - Keynote Day 2 Slides.pdf
 
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
In 2015, I used to write extensions for Joomla, WordPress, phpBB3, etc and I ...
 
2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx2024 RoOUG Security model for the cloud.pptx
2024 RoOUG Security model for the cloud.pptx
 
First Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User EndpointsFirst Steps with Globus Compute Multi-User Endpoints
First Steps with Globus Compute Multi-User Endpoints
 
Enterprise Resource Planning System in Telangana
Enterprise Resource Planning System in TelanganaEnterprise Resource Planning System in Telangana
Enterprise Resource Planning System in Telangana
 
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERRORTROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
TROUBLESHOOTING 9 TYPES OF OUTOFMEMORYERROR
 
How to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good PracticesHow to Position Your Globus Data Portal for Success Ten Good Practices
How to Position Your Globus Data Portal for Success Ten Good Practices
 
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoamOpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
OpenFOAM solver for Helmholtz equation, helmholtzFoam / helmholtzBubbleFoam
 
Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024Globus Connect Server Deep Dive - GlobusWorld 2024
Globus Connect Server Deep Dive - GlobusWorld 2024
 

Functional DDD

  • 1. Functional Domain Driven Design disclaimer: is still a “work in progress”
  • 2. Focus on the domain and domain logic rather than technology (Eric Evans)
  • 3. Why not with a functional approach?
  • 4. A monad is a triple (T, η, μ) where T is an endofunctor T: X->X and η: I->T and μ: T x T- >T are 2 natural transformations satisfying these laws: • Identity law: μ(η(T)) = T = μ(T(η)) • Associative law: μ(μ(T × T) × T)) = μ(T × μ(T × T)) A monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor What is a monad?
  • 5.
  • 6. software developer @ codiceplastico @amelchiori alessandro@codiceplastico.com About me
  • 7. F#: a gentle introduction
  • 8. let myString = "original value" let myString = "new value” Immutability: values, not variables! Duplicate definition of value ‘myString’
  • 9. let add x y = x + y add 2 2 x:int -> y:int -> int Type inference
  • 10. void ProcessItems(Item[] items, Action<Item> action) { for(int i = 0; i < items.Length; i++) { var item = items[i]; action(item); } } Recursion
  • 11. let rec processItems action = function | [] -> () | head :: tail -> action head; processItems tail Recursion
  • 12. let add x y = x + y x:int -> y:int -> int Partial function application let add5 x = add 5 x:int -> int let value = add5 10 (value = 15)
  • 13. let f x = x * x x:int -> int let g x = -x/2 + 5 x:int -> int Functions composition let (<<) f g x = f (g x) ('b -> 'c) -> ('a -> 'b) -> 'a -> ’c let h x = f << g x:int -> int
  • 14. let square x = x * x let add x y = x + y let toString x = x.ToString() let complexFunction x = toString (add 5 (square x)) Pipeline operator let (|>) x f = f x let complexFunction x = x |> square |> add 5 |> toString
  • 15. let div x y = x / y x:int -> y:int -> int div 10 5 // 2 div 10 0 // System.DivideByZeroException Option type let safeDiv x y = if y = 0 then None else Some(x/y) x:int -> y:int -> int option
  • 16. let safeDiv x y = match y with | 0 -> None | _ -> Some(x/y) Pattern matching let safeDiv x y = match y with | 0 -> None | 1 -> Some(x/y) Incomplete pattern matches on this expression. For example, the value '2' may indicate a case not covered by the pattern(s)
  • 17. type State = | On | Off let x = On let y = Off Discriminated unions
  • 18. let div (x, y) = … (int * int) - > int Tuples let div (x, y) = match (x, y) with | (_, 0) -> None | (_, _) -> Some(x/ y)
  • 19. type site = { Title : string; Url : string } Records let homepage = { Title = "Google"; Url = "http://www.google.com" } let next = { homepage with Title = "NextPage" }
  • 21. public class Company { public String BusinessName { get; set; } public String TaxCode { get; set; } public String VatNumber { get; set; } public String AssignedBank { get; set; } public Boolean IsBankAuthorized { get; set; } }
  • 22. Value object An immutable object, like money or a date range, whose equality isn't based on identity (in general equality is based on all fields equality) Martin Fowler
  • 23. Value object An immutable object, like money or a date range, whose equality isn't based on identity (in general equality is based on all fields equality) Martin Fowler
  • 24. public class CompanyProfile { public String BusinessName { get; private set; } public String TaxCode { get; private set; } public String VatNumber { get; private set; } public CompanyProfile(String businessName, String taxCode, String vatNumber=null) { // check if parameters are valid BusinessName = businessName; TaxCode = taxCode; VatNumber = vatNumber; } } Value object
  • 25. public class CompanyProfile { // same as before… public override Boolean Equals(Object other) { var target = other as CompanyProfile; return target == null ? false : target.BusinessName == this.BusinessName && target.TaxCode == this.TaxCode && target.VatCode == this.VatCode; } public override Int32 GetHashCode() { // ... } } Value object’s equality
  • 26. type CompanyProfile = { BusinessName : string; TaxCode : string; VatNumber : string } Value object in F# option; let profile = { BusinessName = “CodicePlastico”; TaxNumber = “1234567890”; }
  • 27. Ubiquitous Language is the concept of defining a language (spoken and written) that is equally used across developers and domain experts Ubiquitous language
  • 28. public class Company { ... public String AssignedBank { get; set; } public Boolean IsBankAuthorized { get; set; } } Ubiquitous language
  • 29. Rule 1: A company must have a bank to work with Rule 2: A company can be authorized to work with its assigned bank Rule 3: A company can be not authorized to work with its assigned bank Business logic
  • 30. Make illegal states unrepresentable Ubiquitous language
  • 31. type Bank = Bank of string type UnauthorizedBank = UnauthorizedBank of Bank type AuthorizedBank = AuthorizedBank of Bank type AssignedBank = | Unauthorized of UnauthorizedBank | Authorized of AuthorizedBank Business logic in F#
  • 32. type CompanyProfile = { BusinessName: string, TaxCode: string, VatCode: string option } type Bank = Bank of string type UnauthorizedBank = UnauthorizedBank of Bank type AuthorizedBank = AuthorizedBank of Bank type AssignedBank = | Unauthorized of UnauthorizedBank | Authorized of AuthorizedBank type Company = { Profile: CompanyProfile, Bank: AssignedBank } Ubiquitous language to the rescue
  • 33. The central idea of specification is to separate the statement of how to match a candidate, from the candidate object that it is matched against Specification
  • 34. type SpecificationResult = | Success | Failure of string type Spec<'a> = 'a -> SpecificationResult Specification
  • 35. type Category = | Default | Premium | Gold type Customer = { Name: string; Category: Category; } Specification: our (simple) domain type Item = { Code: string; Quantity: int; } type Order = { Number: string; Customer: Customer; Items: Item list; }
  • 36. let isOrderFullFilled : Spec<Order> = let p order = match Seq.isEmpty order.Items with | true -> Failure("Items' list empty") | false -> Success in p let isGoldCustomer : Spec<Customer> = let p customer = match customer.Category with | Gold -> Success | _ -> Failure("No-gold customer") in p Specification
  • 37. let And (left: Spec<'a>) (right: Spec<'a>) : Spec<'a> = let p entity = match left entity with | Success -> right entity | _ -> Failure("And specification is not satisfied") in p Specification
  • 38. let order = { Number = "1234"; Customer = { Name = "Alessandro"; Category = Gold}; Items = [ { Code = "Code1"; Quantity = 1}; { Code = "Code2"; Quantity = 2}; ]; } let isOrderValid = And isOrderFullFilled (adapt isGoldCustomer (fun order -> order.Customer)) let isValid = isOrderValid order Specification
  • 39. CQRS & Event Sourcing
  • 40. A single model cannot be appropriate for reporting, searching and transactional behavior Greg Young CQRS
  • 41. State transition are an important part of our problem space and should be modeled within our domain Greg Young Event Sourcing
  • 42. public void AddItemToCart(Item item) { // validation if (item == null) throw new ArgumentNullException(); // execution _items.Add(item.Id); } Commands, events and…fold (step 1)
  • 43. public void AddItemToCart(Item item) { if (item == null) throw new ArgumentNullException(); var domainEvent = new ItemAddedToCart { CartId = this.Id, ItemId = item.Id }; Apply(domainEvent) } private void Apply(ItemAddedToCart domainEvent) { _items.Add(domainEvent.ItemId); } Commands, events and…fold (step 2)
  • 44. public void AddItemToCart(Item item) { if (item == null) throw new ArgumentNullException(); var domainEvent = new ItemAddedToCart { CartId = this.Id, ItemId = item.Id }; Apply(this, domainEvent) } private void Apply(Cart target, ItemAddedToCart domainEvent) { target._items.Add(domainEvent.ItemId); } Commands, events and…fold (step 3)
  • 45. public static Cart Apply(Cart target, CartCreated domainEvent) { return new Cart { Id = domainEvent.CartId, _items = new String[0] }; } public static Cart Apply(Cart target, ItemAddedToCart domainEvent) { var items = target._items.ToList(); items.Add(domainEvent.ItemId); return new Cart { Id = domainEvent.CartId, _items = items }; } public static Cart Apply(Cart target, ItemRemovedFromCart domainEvent) { var items = target._items.ToList(); items.Remove(domainEvent.ItemId); return new Cart { Id = domainEvent.CartId, _items = items }; } Commands, events and…fold (step 4)
  • 46. Cart.Apply(null, new CartCreated { CartId=1 }) Commands, events and…fold (step 5)
  • 47. Cart.Apply( Cart.Apply(null, new CartCreated { CartId=1}), new ItemAddedToCart { CartId = 1, ItemId = "A" } ) Commands, events and…fold (step 5)
  • 48. Cart.Apply( Cart.Apply( Cart.Apply(null, new CartCreated { CartId=1}), new ItemAddedToCart { CartId = 1, ItemId = "A" } ), new ItemAddedToCart { CartId = 1, ItemId = "B" } ) Commands, events and…fold (step 5)
  • 49. Cart.Apply( Cart.Apply( Cart.Apply( Cart.Apply(null, new CartCreated { CartId=1}), new ItemAddedToCart { CartId = 1, ItemId = "A" } ), new ItemAddedToCart { CartId = 1, ItemId = "B" } ), new ItemRemovedFromCart { CartId = 1, ItemId = "A" } ) Commands, events and…fold (step 5)
  • 50. Executing a command: type Exec = ( CartState * Command ) -> DomainEvent Applying an event: type Apply = ( CartState * DomainEvent ) -> CartState Commands, events and…fold (step 6)
  • 51. type Command = | Create of string | AddItem of int | RemoveItem of int | RemoveAllItems | Checkout type Event = | Created of string | ItemAdded of int | ItemRemoved of int | AllItemsRemoved | Checkedout Commands, events and…fold (step 7)
  • 52. type CartState = { Name: string; Items: List<int>; Active: bool; } let apply state = function | Created x -> { Cart.empty with Name = x } | ItemAdded x -> { state with Items = List.append state.Items [x] } | ItemRemoved x -> { state with Items = List.filter (fun i -> i <> x ) state.Items } | Removed _ -> { state with Items = List.empty } | Checkedout _ -> { state with Active = false } Commands, events and…fold (step 8)
  • 53. let domainEvents = [ Created("cart1"); ItemAdded(1); ItemAdded(2); Removed; ItemAdded(3); Checkedout; ] let state = List.fold apply Cart.empty domainEvents Commands, events and…fold (step 9)
  • 54. Tackling Complexity in the Heart of Software Eric Evans …but, when DDD?