SlideShare une entreprise Scribd logo
1  sur  86
Télécharger pour lire hors ligne
Architectural Patterns
in Building Modular
Domain Models
Debasish Ghosh
@debasishg
Architectural Patterns
in Building Modular
Domain Models
Debasish Ghosh
@debasishg
Architectural Patterns
in Building Modular
Domain Models
Debasish Ghosh
@debasishg
Architectural Patterns
in Building Modular
Domain Models
Debasish Ghosh
@debasishg
— John Hughes in Why Functional Programming Matters
https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf
“[..] modularity is the key to successful programming. Languages
that aim to improve productivity must support modular programming well.
But new scope rules and mechanisms for separate compilation are not
enough — modularity means more than modules. Our ability to
decompose a problem into parts depends directly on our ability to glue
solutions together.To support modular programming, a language must
provide good glue. [..] Using these glues one can modularize programs in
new and useful ways[…]. Smaller and more general modules can be reused
more widely, easing subsequent programming.This explains why functional
programs are so much smaller and easier to write than conventional
ones.”
Intent
• Domain Model
• Domain Model Algebra
• Algebraic Combinators
• Compositionality
• Algebra as the basis of modularization of domain models
• Algebraic effects to keep your domain model pure,
modular and compositional
Patterns of modularization of domain models
Algebraic patterns of modularization of domain models
Algebraic patterns of modularization of domain models
using pure values
Algebraic patterns of modularization of domain models
using pure values as effects
Algebraic patterns of modularization of domain models
using pure values as effects
even in the presence of side-effects
Domain Modeling
Domain Modeling
(Functional)
What is a domain model ?
A domain model in problem solving and software engineering is a
conceptual model of all the topics related to a specific problem. It
describes the various entities, their attributes, roles, and
relationships, plus the constraints that govern the problem domain.
It does not describe the solutions to the problem.
Wikipedia (http://en.wikipedia.org/wiki/Domain_model)
The Functional Lens ..
“domain API evolution through algebraic
composition”
The Functional Lens ..
“domain API evolution through algebraic
composition”
Building larger domain behaviours
out of smaller ones
The Functional Lens ..
“domain API evolution through algebraic
composition”
Use composition
of pure functions and types
Your domain model is
a function
Your domain model is
a function
Your domain model is
a collection of
functions
Your domain model is
a collection of
functions
some simpler models are ..
https://msdn.microsoft.com/en-us/library/jj591560.aspx
A Bounded Context
• has a consistent vocabulary
• a set of domain behaviors modeled as
functions on domain objects
implemented as types
• each of the behaviors honor a set of
business rules
• related behaviors grouped as modules
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { m[T1,T2,..] | T(i) ∈ Types }
Module = { f(x,y,..) | p(x,y) ∈ Domain Rules }
• domain function
• on an object of types x, y, ..
• composes with other functions
• closed under composition
• business rules
• Functions / Morphisms
• Types / Sets
• Composition
• Rules / Laws
algebra
Domain Model Algebra
explicit verifiable
• types
• type constraints
• functions between types
• type constraints
• more constraints if you have DT
• algebraic property based testing
(algebra of types, functions & laws
of the solution domain model)
Domain Model Algebra
• Algebra as the glue for binding domain model
artifacts
• Algebras evolve by composition
Reusable combinators
Build larger abstractions out
of smaller ones using properties
of compositionality
Algebra of a Monoid
trait Semigroup[A] {
def combine(x: A, y: A): A
}
trait Monoid[A] extends Semigroup[A] {
def empty: A
}
parametricity
Algebra of a Foldable
trait Foldable[F[_]] {
def foldleft[A,B](as: F[A], z: B, f: (B, A) => B): B
def foldMap[A,B](as: F[A], f: A => B)
(implicit m: Monoid[B]): B =
foldleft(as, m.zero,
(b: B, a: A) => m.combine(b, f(a)))
}
Algebraic Combinators
def mapReduce[F[_], A, B](as: F[A])(f: A => B)
(implicit fd: Foldable[F], m: Monoid[B]): B =
fd.foldMap(as)(f)
Built out of PURE algebra ONLY
Uses the algebras of Monoid and Foldable
Domain Behaviors
object Payments extends .. {
def valuation(payments: List[Payment]): Money = {
implicit val m: Monoid[Money] = MoneyAddMonoid
mapReduce(payments)(creditAmount)
}
def maxPayment(payments: List[Payment]): Money = {
implicit val m: Monoid[Money] = MoneyOrderMonoid
mapReduce(payments)(creditAmount)
}
}
Algebras => Functional Patterns
• Bits of domain elements evolving from reusable
generic algebras
• The algebras we reuse already exist - as a designer
we provide the implementation of those
algebras in the context of the domain model
• The algebras are the patterns, the
implementations are instances of patterns in the
context of our domain model
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { m[T1,T2,..] | T(i) ∈ Types }
Module = { f(x,y,..) | p(x,y) ∈ Domain Rules }
• domain function
• on an object of types x, y
• composes with other functions
• closed under composition
• business rules
• domain function
• on an object of type x, y, ..
• composes with other functions
• closed under composition
Domain Model = ∪(i) Bounded Context(i)
Bounded Context = { m[T1,T2,..] | T(i) ∈ Types }
Module = { f(x, y, .. ) | p(x) ∈ Domain Rules }
• business rules
(algebra)
(algebra)
Given all the properties of algebra, can we
consider algebraic composition to be the
basis of designing, implementing and modularizing
domain models ?
Problem Domain
Bank
Account
Trade
Customer
...
...
...
Problem Domain
...
entities
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Problem Domain
...
entities
behaviors
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Problem Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
do trade
process
execution
place
order
Solution Domain
...
behaviors
Functions
([Type] => Type)
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
entities
behaviors
functions
([Type] => Type)
algebraic data type
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
([Type] => Type)
algebraic data type business rules / invariants
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
([Type] => Type)
algebraic data type business rules / invariants
Monoid
Monad
...
reusable algebra
Bank
Account
Trade
Customer
...
...
...
do trade
process
execution
place
order
Solution Domain
...
market
regulations
tax laws
brokerage
commission
rates
...
entities
behaviors
laws
functions
([Type] => Type)
algebraic data type business rules / invariants
Monoid
Monad
...
Domain Algebra
Client places order
- flexible format
1
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
1 2
Client places order
- flexible format
Transform to internal domain
model entity and place for execution
Trade & Allocate to
client accounts
1 2
3
def fromClientOrder: ClientOrder => Order
def execute(market: Market, brokerAccount: Account)
: Order => List[Execution]
def allocate(accounts: List[Account])
: List[Execution] => List[Trade]
trait Trading {
}
trait TradeComponent extends Trading
with Logging with Auditing
algebra of domain
behaviors / functions
functions aggregate
upwards into modules
modules aggregate
into larger modules
Takeaways ..
• Publish as much domain behavior as you can through the
algebra of your APIs. Since algebra is compositional, it’s easy
to extend later by stacking abstractions on top of existing ones.
• Types are important but in domain modeling, names must come
from the vocabulary of the domain - Ubiquitous Language
• Group related functions into modules. Modules are also
compositional in Scala.
• Functions aggregate into modules, modules aggregate into
components.
.. so we have a decent algebra of our module, the
names reflect the appropriate artifacts from the
domain (ubiquitous language), the types are
well published and we are quite explicit in what
the behaviors do ..
1. Compositionality - How do we compose
the 3 behaviors that we published to
generate trade in the market and allocate
to client accounts ?
2. Side-effects - We need to compose them
alongside all side-effects that form a core
part of all non trivial domain model
implementations
• Error handling ?
• throw / catch exceptions is not RT
• Partiality ?
• partial functions can report runtime exceptions if invoked
with unhandled arguments (violates RT)
• Reading configuration information from environment ?
• may result in code repetition if not properly handled
• Logging ?
• side-effects
Side-effects
Side-effects
• Database writes
• Writing to a message queue
• Reading from stdin / files
• Interacting with any external resource
• Changing state in place
modularity
side-effects don’t compose
.. the semantics of compositionality ..
in the presence of side-effects
The solution is to abstract side-effects into data
types that are pure values for which
referential transparency holds and which can
be composed with other pure functional
abstractions
The solution is to abstract side-effects into
data types that are pure values for which
referential transparency holds and which can be
composed with other pure functional
abstractions
The solution is to abstract side-effects into
data type-constructors that are pure values
for which referential transparency holds and which
can be composed with other pure
functional abstractions
Effects
Option[A]
Either[A,B]
(partiality)
(disjunction)
List[A]
(non-determinism)
Reader[E,A]
(read from environment aka dependency Injection)
Writer[W,A]
(logging)
State[S,A]
(state management)
IO[A]
(external side-effects)
.. and there are many many more ..
F[A]
The answer that the
effect computesThe additional stuff
modeling the computation
• The F[_] that we saw is an opaque type - it
has no denotation till we give it one
• The denotation that we give to F[_] depends
on the semantics of compositionality that we
would like to have for our domain model
behaviors
def fromClientOrder: ClientOrder => F[Order]
def execute(market: Market, brokerAccount: Account)
: Order => F[List[Execution]]
def allocate(accounts: List[Account])
: List[Execution] => F[List[Trade]]
trait Trading {
}
• We haven’t yet given any denotation to the effect type
• We haven’t yet committed to any concrete effect type
• .. we have intentionally kept the algebra open
for interpretation ..
• .. there are use cases where you would like to
have multiple interpreters for the same
algebra ..
class TradingInterpreter[F[_]]
(implicit me: MonadError[F, Throwable])
extends Trading {
def fromClientOrder: ClientOrder => F[Order] = makeOrder(_) match {
case Left(dv) => me.raiseError(new Exception(dv.message))
case Right(o) => o.pure[F]
}
def execute(market: Market, brokerAccount: Account)
: Order => F[List[Execution]] = ...
def allocate(accounts: List[Account])
: List[Execution] => F[List[Trade]] = ...
}
One Sample Interpreter
• .. one lesson in modularity - commit to a
concrete implementation as late as
possible in the design ..
• .. we have just indicated that we want a
monadic effect - we haven’t committed to
any concrete monad type even in the
interpreter ..
The Program
def tradeGeneration[M[_]: Monad](T: Trading[M]) = for {
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
} yield trades
The Program
def tradeGeneration[M[_]: Monad](T: Trading[M]) = for {
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
} yield trades
depends on the
algebra only
The Program
def tradeGeneration[M[_]: Monad](T: Trading[M]) = for {
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
} yield trades
depends on the
algebra only
the story of what needs
to be done, NOT HOW
The Program
import cats.effect.IO
def tradeGeneration[M[_]: Monad](T: Trading[M]) = for {
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
} yield trades
object TradingComponent extends TradingInterpreter[IO]
tradeGeneration(TradingComponent).unsafeRunSync
The Program
import monix.eval.Task
def tradeGeneration[M[_]: Monad](T: Trading[M]) = for {
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
} yield trades
object TradingComponent extends TradingInterpreter[Task]
tradeGeneration(TradingComponent)
The Program
def tradeGenerationLoggable[M[_]: Monad]
(T: Trading[M], L: Logging[M]) = for {
_ <- L.info("starting order processing")
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
_ <- L.info("allocation done")
} yield trades
object TradingComponent extends TradingInterpreter[IO]
object LoggingComponent extends LoggingInterpreter[IO]
tradeGenerationLoggable(TradingComponent, LoggingComponent).unsafeRunSync
Raise the level of
abstraction
trait Trading[F[_]] {
def fromClientOrder
: Kleisli[F, ClientOrder, Order]
def execute(market: Market, brokerAccount: Account)
: Kleisli[F, Order, List[Execution]]
def allocate(accounts: List[Account])
: Kleisli[F, List[Execution], List[Trade]]
}
The Program
def tradeGeneration[M[_]: Monad](T: Trading[M])
: Kleisli[M, ClientOrder, List[Trade]] = {
T.fromClientOrder andThen
T.execute(m1, ba) andThen
T.allocate(List(ca1, ca2, ca3))
}
object TradingComponent extends TradingInterpreter[IO]
val tk = tradeGeneration(TradingComponent)
tk(cor).unsafeRunSync
Effects
Side-effects
- Rob Norris at scale.bythebay.io talk - 2017 (https://www.youtube.com/
watch?v=po3wmq4S15A)
“Effects and side-effects are not the same thing. Effects are
good, side-effects are bugs.Their lexical similarity is really
unfortunate because people often conflate the two ideas”
Testing
• Testable

• We did not commit to a
concrete type upfront - some
virtues of being lazy with
evaluation

• For monadic effects, easier
testing with the Id monad -
just use a different
implementation for the same
algebra
def tradeGenerationLoggable[M[_]: Monad]
(T: Trading[M], L: Logging[M]) = for {
_ <- L.info("starting order processing")
order <- T.fromClientOrder(cor)
executions <- T.execute(m1, ba, order)
trades <- T.allocate(List(ca1, ca2, ca3), executions)
_ <- L.info("allocation done")
} yield trades
Takeaways
• Modularity in the presence of side-effects is a
challenge
• Algebraic modeling is the key to address this
• Effects as algebras are pure values that can
compose based on laws
• Determine the type of effect based on the
semantics of compositionality of your domain
behaviors
Takeaways
• Compose effects parametrically
• Honor the law of using the least powerful
abstraction that works
• Be polymorphic (parametric) as early as you
can, commit to concrete types as late as you
can
Questions?

Contenu connexe

Tendances

DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDebasish Ghosh
 
Functional Patterns in Domain Modeling
Functional Patterns in Domain ModelingFunctional Patterns in Domain Modeling
Functional Patterns in Domain ModelingDebasish Ghosh
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDebasish Ghosh
 
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automationJS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automationJSFestUA
 
DIWE - Working with MySQL Databases
DIWE - Working with MySQL DatabasesDIWE - Working with MySQL Databases
DIWE - Working with MySQL DatabasesRasan Samarasinghe
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basicsVu Tran Lam
 
Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Vu Tran Lam
 
classes and objects in C++
classes and objects in C++classes and objects in C++
classes and objects in C++HalaiHansaika
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture ThreeAngelo Corsaro
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressBrendan Eich
 

Tendances (13)

DSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic modelDSL - expressive syntax on top of a clean semantic model
DSL - expressive syntax on top of a clean semantic model
 
Functional Patterns in Domain Modeling
Functional Patterns in Domain ModelingFunctional Patterns in Domain Modeling
Functional Patterns in Domain Modeling
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 
Dependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake PatternDependency Injection in Scala - Beyond the Cake Pattern
Dependency Injection in Scala - Beyond the Cake Pattern
 
Templates in c++
Templates in c++Templates in c++
Templates in c++
 
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automationJS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
JS Fest 2019. Mauricio Palma. You can’t read this sentence - A11y automation
 
DIWE - Working with MySQL Databases
DIWE - Working with MySQL DatabasesDIWE - Working with MySQL Databases
DIWE - Working with MySQL Databases
 
Session 2 - Objective-C basics
Session 2 - Objective-C basicsSession 2 - Objective-C basics
Session 2 - Objective-C basics
 
Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)Session 3 - Object oriented programming with Objective-C (part 1)
Session 3 - Object oriented programming with Objective-C (part 1)
 
Basic c#
Basic c#Basic c#
Basic c#
 
classes and objects in C++
classes and objects in C++classes and objects in C++
classes and objects in C++
 
Programming in Scala - Lecture Three
Programming in Scala - Lecture ThreeProgramming in Scala - Lecture Three
Programming in Scala - Lecture Three
 
Value objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progressValue objects in JS - an ES7 work in progress
Value objects in JS - an ES7 work in progress
 

Similaire à Architectural Patterns in Building Modular Domain Models

Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven DesignMuhammad Ali
 
Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Sandro Mancuso
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoJAXLondon2014
 
Prophecy Of Design Patterns
Prophecy Of Design PatternsProphecy Of Design Patterns
Prophecy Of Design Patternspradeepkothiyal
 
Domain Driven Design Introduction
Domain Driven Design IntroductionDomain Driven Design Introduction
Domain Driven Design Introductionwojtek_s
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programmingDhaval Dalal
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptVGaneshKarthikeyan
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptVGaneshKarthikeyan
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptVGaneshKarthikeyan
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven DesignNader Albert
 
Functional Effects - Part 1
Functional Effects - Part 1Functional Effects - Part 1
Functional Effects - Part 1Philip Schwarz
 
An Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPAn Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPChris Renner
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)Tom Kocjan
 
Domain-Driven Design at ZendCon 2012
Domain-Driven Design at ZendCon 2012Domain-Driven Design at ZendCon 2012
Domain-Driven Design at ZendCon 2012Bradley Holt
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingShine Xavier
 
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
Seminar - Scalable Enterprise Application Development Using DDD and CQRSSeminar - Scalable Enterprise Application Development Using DDD and CQRS
Seminar - Scalable Enterprise Application Development Using DDD and CQRSMizanur Sarker
 
Design Patterns By Sisimon Soman
Design Patterns By Sisimon SomanDesign Patterns By Sisimon Soman
Design Patterns By Sisimon SomanSisimon Soman
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Sandro Mancuso
 

Similaire à Architectural Patterns in Building Modular Domain Models (20)

Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
SDWest2005Goetsch
SDWest2005GoetschSDWest2005Goetsch
SDWest2005Goetsch
 
Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014Crafted Design - LJC World Tour Mash Up 2014
Crafted Design - LJC World Tour Mash Up 2014
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro Mancuso
 
Prophecy Of Design Patterns
Prophecy Of Design PatternsProphecy Of Design Patterns
Prophecy Of Design Patterns
 
Sda 9
Sda   9Sda   9
Sda 9
 
Domain Driven Design Introduction
Domain Driven Design IntroductionDomain Driven Design Introduction
Domain Driven Design Introduction
 
Booting into functional programming
Booting into functional programmingBooting into functional programming
Booting into functional programming
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
 
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.pptUNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
UNIT-I(Unified_Process_and_Use Case_Diagrams)_OOAD.ppt
 
Domain Driven Design
Domain Driven DesignDomain Driven Design
Domain Driven Design
 
Functional Effects - Part 1
Functional Effects - Part 1Functional Effects - Part 1
Functional Effects - Part 1
 
An Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHPAn Introduction to Domain Driven Design in PHP
An Introduction to Domain Driven Design in PHP
 
Domain Driven Design (DDD)
Domain Driven Design (DDD)Domain Driven Design (DDD)
Domain Driven Design (DDD)
 
Domain-Driven Design at ZendCon 2012
Domain-Driven Design at ZendCon 2012Domain-Driven Design at ZendCon 2012
Domain-Driven Design at ZendCon 2012
 
Fuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional ProgrammingFuel Up JavaScript with Functional Programming
Fuel Up JavaScript with Functional Programming
 
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
Seminar - Scalable Enterprise Application Development Using DDD and CQRSSeminar - Scalable Enterprise Application Development Using DDD and CQRS
Seminar - Scalable Enterprise Application Development Using DDD and CQRS
 
Design Patterns By Sisimon Soman
Design Patterns By Sisimon SomanDesign Patterns By Sisimon Soman
Design Patterns By Sisimon Soman
 
Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014Crafted Design - ITAKE 2014
Crafted Design - ITAKE 2014
 

Dernier

Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfDrew Moseley
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...OnePlan Solutions
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxAndreas Kunz
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecturerahul_net
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commercemanigoyal112
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 

Dernier (20)

Comparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdfComparing Linux OS Image Update Models - EOSS 2024.pdf
Comparing Linux OS Image Update Models - EOSS 2024.pdf
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
Tech Tuesday - Mastering Time Management Unlock the Power of OnePlan's Timesh...
 
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptxUI5ers live - Custom Controls wrapping 3rd-party libs.pptx
UI5ers live - Custom Controls wrapping 3rd-party libs.pptx
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort ServiceHot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
Hot Sexy call girls in Patel Nagar🔝 9953056974 🔝 escort Service
 
Understanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM ArchitectureUnderstanding Flamingo - DeepMind's VLM Architecture
Understanding Flamingo - DeepMind's VLM Architecture
 
Cyber security and its impact on E commerce
Cyber security and its impact on E commerceCyber security and its impact on E commerce
Cyber security and its impact on E commerce
 
How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 

Architectural Patterns in Building Modular Domain Models

  • 1. Architectural Patterns in Building Modular Domain Models Debasish Ghosh @debasishg
  • 2. Architectural Patterns in Building Modular Domain Models Debasish Ghosh @debasishg
  • 3. Architectural Patterns in Building Modular Domain Models Debasish Ghosh @debasishg
  • 4. Architectural Patterns in Building Modular Domain Models Debasish Ghosh @debasishg
  • 5. — John Hughes in Why Functional Programming Matters https://www.cs.kent.ac.uk/people/staff/dat/miranda/whyfp90.pdf “[..] modularity is the key to successful programming. Languages that aim to improve productivity must support modular programming well. But new scope rules and mechanisms for separate compilation are not enough — modularity means more than modules. Our ability to decompose a problem into parts depends directly on our ability to glue solutions together.To support modular programming, a language must provide good glue. [..] Using these glues one can modularize programs in new and useful ways[…]. Smaller and more general modules can be reused more widely, easing subsequent programming.This explains why functional programs are so much smaller and easier to write than conventional ones.”
  • 6. Intent • Domain Model • Domain Model Algebra • Algebraic Combinators • Compositionality • Algebra as the basis of modularization of domain models • Algebraic effects to keep your domain model pure, modular and compositional
  • 7. Patterns of modularization of domain models
  • 8. Algebraic patterns of modularization of domain models
  • 9. Algebraic patterns of modularization of domain models using pure values
  • 10. Algebraic patterns of modularization of domain models using pure values as effects
  • 11. Algebraic patterns of modularization of domain models using pure values as effects even in the presence of side-effects
  • 14. What is a domain model ? A domain model in problem solving and software engineering is a conceptual model of all the topics related to a specific problem. It describes the various entities, their attributes, roles, and relationships, plus the constraints that govern the problem domain. It does not describe the solutions to the problem. Wikipedia (http://en.wikipedia.org/wiki/Domain_model)
  • 15. The Functional Lens .. “domain API evolution through algebraic composition”
  • 16. The Functional Lens .. “domain API evolution through algebraic composition” Building larger domain behaviours out of smaller ones
  • 17. The Functional Lens .. “domain API evolution through algebraic composition” Use composition of pure functions and types
  • 18.
  • 19.
  • 20.
  • 21.
  • 22. Your domain model is a function
  • 23. Your domain model is a function
  • 24. Your domain model is a collection of functions
  • 25. Your domain model is a collection of functions some simpler models are ..
  • 27. A Bounded Context • has a consistent vocabulary • a set of domain behaviors modeled as functions on domain objects implemented as types • each of the behaviors honor a set of business rules • related behaviors grouped as modules
  • 28. Domain Model = ∪(i) Bounded Context(i) Bounded Context = { m[T1,T2,..] | T(i) ∈ Types } Module = { f(x,y,..) | p(x,y) ∈ Domain Rules } • domain function • on an object of types x, y, .. • composes with other functions • closed under composition • business rules
  • 29. • Functions / Morphisms • Types / Sets • Composition • Rules / Laws algebra
  • 30. Domain Model Algebra explicit verifiable • types • type constraints • functions between types • type constraints • more constraints if you have DT • algebraic property based testing (algebra of types, functions & laws of the solution domain model)
  • 31. Domain Model Algebra • Algebra as the glue for binding domain model artifacts • Algebras evolve by composition Reusable combinators Build larger abstractions out of smaller ones using properties of compositionality
  • 32. Algebra of a Monoid trait Semigroup[A] { def combine(x: A, y: A): A } trait Monoid[A] extends Semigroup[A] { def empty: A } parametricity
  • 33. Algebra of a Foldable trait Foldable[F[_]] { def foldleft[A,B](as: F[A], z: B, f: (B, A) => B): B def foldMap[A,B](as: F[A], f: A => B) (implicit m: Monoid[B]): B = foldleft(as, m.zero, (b: B, a: A) => m.combine(b, f(a))) }
  • 34. Algebraic Combinators def mapReduce[F[_], A, B](as: F[A])(f: A => B) (implicit fd: Foldable[F], m: Monoid[B]): B = fd.foldMap(as)(f) Built out of PURE algebra ONLY Uses the algebras of Monoid and Foldable
  • 35. Domain Behaviors object Payments extends .. { def valuation(payments: List[Payment]): Money = { implicit val m: Monoid[Money] = MoneyAddMonoid mapReduce(payments)(creditAmount) } def maxPayment(payments: List[Payment]): Money = { implicit val m: Monoid[Money] = MoneyOrderMonoid mapReduce(payments)(creditAmount) } }
  • 36. Algebras => Functional Patterns • Bits of domain elements evolving from reusable generic algebras • The algebras we reuse already exist - as a designer we provide the implementation of those algebras in the context of the domain model • The algebras are the patterns, the implementations are instances of patterns in the context of our domain model
  • 37. Domain Model = ∪(i) Bounded Context(i) Bounded Context = { m[T1,T2,..] | T(i) ∈ Types } Module = { f(x,y,..) | p(x,y) ∈ Domain Rules } • domain function • on an object of types x, y • composes with other functions • closed under composition • business rules
  • 38. • domain function • on an object of type x, y, .. • composes with other functions • closed under composition Domain Model = ∪(i) Bounded Context(i) Bounded Context = { m[T1,T2,..] | T(i) ∈ Types } Module = { f(x, y, .. ) | p(x) ∈ Domain Rules } • business rules (algebra) (algebra)
  • 39. Given all the properties of algebra, can we consider algebraic composition to be the basis of designing, implementing and modularizing domain models ?
  • 46. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions ([Type] => Type) algebraic data type business rules / invariants
  • 47. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions ([Type] => Type) algebraic data type business rules / invariants Monoid Monad ... reusable algebra
  • 48. Bank Account Trade Customer ... ... ... do trade process execution place order Solution Domain ... market regulations tax laws brokerage commission rates ... entities behaviors laws functions ([Type] => Type) algebraic data type business rules / invariants Monoid Monad ... Domain Algebra
  • 49. Client places order - flexible format 1
  • 50. Client places order - flexible format Transform to internal domain model entity and place for execution 1 2
  • 51. Client places order - flexible format Transform to internal domain model entity and place for execution Trade & Allocate to client accounts 1 2 3
  • 52. def fromClientOrder: ClientOrder => Order def execute(market: Market, brokerAccount: Account) : Order => List[Execution] def allocate(accounts: List[Account]) : List[Execution] => List[Trade] trait Trading { } trait TradeComponent extends Trading with Logging with Auditing algebra of domain behaviors / functions functions aggregate upwards into modules modules aggregate into larger modules
  • 53. Takeaways .. • Publish as much domain behavior as you can through the algebra of your APIs. Since algebra is compositional, it’s easy to extend later by stacking abstractions on top of existing ones. • Types are important but in domain modeling, names must come from the vocabulary of the domain - Ubiquitous Language • Group related functions into modules. Modules are also compositional in Scala. • Functions aggregate into modules, modules aggregate into components.
  • 54. .. so we have a decent algebra of our module, the names reflect the appropriate artifacts from the domain (ubiquitous language), the types are well published and we are quite explicit in what the behaviors do ..
  • 55. 1. Compositionality - How do we compose the 3 behaviors that we published to generate trade in the market and allocate to client accounts ? 2. Side-effects - We need to compose them alongside all side-effects that form a core part of all non trivial domain model implementations
  • 56. • Error handling ? • throw / catch exceptions is not RT • Partiality ? • partial functions can report runtime exceptions if invoked with unhandled arguments (violates RT) • Reading configuration information from environment ? • may result in code repetition if not properly handled • Logging ? • side-effects Side-effects
  • 57. Side-effects • Database writes • Writing to a message queue • Reading from stdin / files • Interacting with any external resource • Changing state in place
  • 59. .. the semantics of compositionality .. in the presence of side-effects
  • 60. The solution is to abstract side-effects into data types that are pure values for which referential transparency holds and which can be composed with other pure functional abstractions
  • 61. The solution is to abstract side-effects into data types that are pure values for which referential transparency holds and which can be composed with other pure functional abstractions
  • 62. The solution is to abstract side-effects into data type-constructors that are pure values for which referential transparency holds and which can be composed with other pure functional abstractions Effects
  • 63. Option[A] Either[A,B] (partiality) (disjunction) List[A] (non-determinism) Reader[E,A] (read from environment aka dependency Injection) Writer[W,A] (logging) State[S,A] (state management) IO[A] (external side-effects) .. and there are many many more ..
  • 64. F[A] The answer that the effect computesThe additional stuff modeling the computation
  • 65. • The F[_] that we saw is an opaque type - it has no denotation till we give it one • The denotation that we give to F[_] depends on the semantics of compositionality that we would like to have for our domain model behaviors
  • 66. def fromClientOrder: ClientOrder => F[Order] def execute(market: Market, brokerAccount: Account) : Order => F[List[Execution]] def allocate(accounts: List[Account]) : List[Execution] => F[List[Trade]] trait Trading { } • We haven’t yet given any denotation to the effect type • We haven’t yet committed to any concrete effect type
  • 67. • .. we have intentionally kept the algebra open for interpretation .. • .. there are use cases where you would like to have multiple interpreters for the same algebra ..
  • 68. class TradingInterpreter[F[_]] (implicit me: MonadError[F, Throwable]) extends Trading { def fromClientOrder: ClientOrder => F[Order] = makeOrder(_) match { case Left(dv) => me.raiseError(new Exception(dv.message)) case Right(o) => o.pure[F] } def execute(market: Market, brokerAccount: Account) : Order => F[List[Execution]] = ... def allocate(accounts: List[Account]) : List[Execution] => F[List[Trade]] = ... } One Sample Interpreter
  • 69. • .. one lesson in modularity - commit to a concrete implementation as late as possible in the design .. • .. we have just indicated that we want a monadic effect - we haven’t committed to any concrete monad type even in the interpreter ..
  • 70. The Program def tradeGeneration[M[_]: Monad](T: Trading[M]) = for { order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) } yield trades
  • 71. The Program def tradeGeneration[M[_]: Monad](T: Trading[M]) = for { order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) } yield trades depends on the algebra only
  • 72. The Program def tradeGeneration[M[_]: Monad](T: Trading[M]) = for { order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) } yield trades depends on the algebra only the story of what needs to be done, NOT HOW
  • 73. The Program import cats.effect.IO def tradeGeneration[M[_]: Monad](T: Trading[M]) = for { order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) } yield trades object TradingComponent extends TradingInterpreter[IO] tradeGeneration(TradingComponent).unsafeRunSync
  • 74. The Program import monix.eval.Task def tradeGeneration[M[_]: Monad](T: Trading[M]) = for { order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) } yield trades object TradingComponent extends TradingInterpreter[Task] tradeGeneration(TradingComponent)
  • 75. The Program def tradeGenerationLoggable[M[_]: Monad] (T: Trading[M], L: Logging[M]) = for { _ <- L.info("starting order processing") order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) _ <- L.info("allocation done") } yield trades object TradingComponent extends TradingInterpreter[IO] object LoggingComponent extends LoggingInterpreter[IO] tradeGenerationLoggable(TradingComponent, LoggingComponent).unsafeRunSync
  • 76. Raise the level of abstraction trait Trading[F[_]] { def fromClientOrder : Kleisli[F, ClientOrder, Order] def execute(market: Market, brokerAccount: Account) : Kleisli[F, Order, List[Execution]] def allocate(accounts: List[Account]) : Kleisli[F, List[Execution], List[Trade]] }
  • 77. The Program def tradeGeneration[M[_]: Monad](T: Trading[M]) : Kleisli[M, ClientOrder, List[Trade]] = { T.fromClientOrder andThen T.execute(m1, ba) andThen T.allocate(List(ca1, ca2, ca3)) } object TradingComponent extends TradingInterpreter[IO] val tk = tradeGeneration(TradingComponent) tk(cor).unsafeRunSync
  • 79. - Rob Norris at scale.bythebay.io talk - 2017 (https://www.youtube.com/ watch?v=po3wmq4S15A) “Effects and side-effects are not the same thing. Effects are good, side-effects are bugs.Their lexical similarity is really unfortunate because people often conflate the two ideas”
  • 80. Testing • Testable • We did not commit to a concrete type upfront - some virtues of being lazy with evaluation • For monadic effects, easier testing with the Id monad - just use a different implementation for the same algebra def tradeGenerationLoggable[M[_]: Monad] (T: Trading[M], L: Logging[M]) = for { _ <- L.info("starting order processing") order <- T.fromClientOrder(cor) executions <- T.execute(m1, ba, order) trades <- T.allocate(List(ca1, ca2, ca3), executions) _ <- L.info("allocation done") } yield trades
  • 81.
  • 82.
  • 83.
  • 84. Takeaways • Modularity in the presence of side-effects is a challenge • Algebraic modeling is the key to address this • Effects as algebras are pure values that can compose based on laws • Determine the type of effect based on the semantics of compositionality of your domain behaviors
  • 85. Takeaways • Compose effects parametrically • Honor the law of using the least powerful abstraction that works • Be polymorphic (parametric) as early as you can, commit to concrete types as late as you can