SlideShare uma empresa Scribd logo
1 de 55
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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a Functional DDD

Scala - where objects and functions meet
Scala - where objects and functions meetScala - where objects and functions meet
Scala - where objects and functions meet
Mario Fusco
 
Working With JQuery Part1
Working With JQuery Part1Working With JQuery Part1
Working With JQuery Part1
saydin_soft
 

Semelhante a 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
 

Mais de Alessandro Melchiori

Mais de 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
 

Último

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Último (20)

Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 

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?