Functional Domain Modeling

Functional Domain Modeling

How to apply functional concepts in modelling domain aggregate roots. Shown on example going from typical imperative, into more functional side-effect free one. Examples are in Scala. Presented on DevFest 2013 Vienna

Ff0df969613ac15904f52b8fcf256c67?s=128

Michal Bigos

October 19, 2013
Tweet

Transcript

  1. / Garwan Consulting s.r.o. Functional Domain Modeling Michal Bigos @teliatko

  2. Agenda 1. Example Domain 2. Functional Programming Applied 3. Suitable

    Architecture
  3. Example Domain Order Aggregate Root

  4. Example Domain DDD Recap Related Entities and Value Objects form

    an Aggregate Main entity is Aggregate Root AR is the only referenced Entity from outside AR is Boundary for transactional consistency AR ensures business invariants
  5. Functional Programming Applied Immutable Data Data w/o shared mutable state

    ... no in-place mutation They can be shared freely ... no locks, no semaphores etc. / / D e f i n i t i o n o f c l a s s w i t h v a l u e s i n s t e a d o f v a r i a b l e s c l a s s O r d e r ( i d : O r d e r I d , c u s t o m e r I d : C u s t o m e r I d , s h i p m e n t A d d r e s s : A d d r e s s , l i n e s : V e c t o r [ O r d e r L i n e ] = V e c t o r . e m p t y , c r e a t e d : D a t e T i m e = D a t e T i m e . n o w ( ) ) { . . . }
  6. Functional Programming Applied Pure Functions Functions with no side-effects They

    are referentially transparent / / D e f i n i t i o n o f f u n c t i o n i n s t e a d o f p r o c e d u r e d e f a d d P r o d u c t ( p r o d u c t I d : P r o d u c t I d , q u a n t i t y : I n t , u n i t : P r o d u c t U n i t , p r i c e : B i g D e c i m a l ) : O r d e r = { . . . / / N o s i d e - e f f e c t s i n s i d e , i n c l u d i n g I / O , t h r o w i n g E x c e p t i o n s . . . }
  7. Functional Programming Applied Persistent Data Structures Always preserves the previous

    version of itself when it is modified Effectively immutable with no in-place mutation / / S u p p o s e w e h a v e a v e c t o r o f n u m b e r s . . . v a l n u m b e r s = V e c t o r ( 1 , 2 , 3 ) / / T h e n w e a d d a i t e m t o i t v a l n u m b e r s W i t h F o u r = n u m b e r s : + 4 a s s e r t ( n u m b e r s ! = n u m b e r s W i t h F o u r ) / / y i e l d s t r u e
  8. Functional Programming Applied Algebraic Data Types, take one Domain entities

    and values can be represented using product types case classes are best fit in Scala / / T u p l e i s s i m p l e s t p r o d u c t t y p e v a l u s e r = ( u s e r n a m e , p a s s w o r d ) / / P r o d u c t t y p e v i a c a s e c l a s s c a s e c l a s s O r d e r L i n e ( p r o d u c t I d : P r o d u c t I d , q u a n t i t y : I n t , u n i t : P r o d u c t U n i t , p r i c e : B i g D e c i m a l )
  9. Functional Programming Applied Algebraic Data Types, take two Domain values

    and enums can be represented using sum types Inheritance and sealed traits/classes are best fit in Scala / / E x a m p l e o f s u m - t y p e , O p t i o n f r o m S c a l a l i b r a r y ( c o d e s i m p l i f i e d ) s e a l e d a b s t r a c t c l a s s O p t i o n [ + A ] f i n a l c a s e c l a s s S o m e [ + A ] ( x : A ) e x t e n d s O p t i o n [ A ] c a s e o b j e c t N o n e e x t e n d s O p t i o n [ N o t h i n g ] / / S u m t y p e v i a c a s e o b j e c t s s e a l e d t r a i t P r o d u c t U n i t c a s e o b j e c t P i e c e e x t e n d s P r o d u c t U n i t c a s e o b j e c t K g e x t e n d s P r o d u c t U n i t c a s e o b j e c t L i t r e e x t e n d s P r o d u c t U n i t
  10. Functional Programming Applied Function Composition Functions compose when they cause

    no side-effects Side-effects do not compose s c a l a > d e f f o o ( s o m e t h i n g : S t r i n g ) : S t r i n g = s " f o o ( $ s o m e t h i n g ) " s c a l a > d e f b a r ( s o m e t h i n g : S t r i n g ) : S t r i n g = s " b a r ( $ s o m e t h i n g ) " v a l c o m p o s i t = f o o _ c o m p o s e b a r _ v a l r e v e r s e C o m p o s i t = f o o _ a n d T h e n b a r _ c o m p o s i t ( " a n y t h i n g " ) > f o o ( b a r ( a n y t h i n g ) ) r e v e r s e C o m p o s i t ( " a n y t h i n g " ) > b a r ( f o o ( a n y t h i n g ) )
  11. Functional Programming Applied Combinators Apply high-order functions Glue for chaining

    functions Pure functions as domain invariants and behavior f o u n d m a p { f o u n d L i n e = > p a r t i t i o n s . s u c c e s s } / / | | / / C o m b i n a t o r H i g h - o r d e r f n / / M o n a d i c c h a i n i n g , v i a f o r - c o m p r e h e n s i o n s f o r { _ < - q u a n t i t y I n v a r i a n t ( q u a n t i t y ) _ < - p r i c e I n v a r i a n t ( p r i c e ) ( f o u n d , r e s t ) < - p r o d u c t A l r e a d y E x i s t s ( p r o d u c t I d ) } y i e l d { / * d o s o m e t h i n g * / }
  12. Functional Programming Applied Side Effects FP languages encourage isolating side-effects

    from pure domain logic Known side-effects (not insignigicant) 1. DB access 2. Logging 3. IO operations Example r e s u l t . f o r e a c h { o r d e r = > o r d e r R e p o s i t o r y . s a v e O r U p d a t e ( o r d e r ) }
  13. Suitable Architecture Perception of State Domain state is effectively mutable

    Can retain previous states History of what happened Separation of state and time
  14. Suitable Architecture CQRS with Event Sourcing Every state-modification on domain

    yields event Event stream, all the events applied on domain Commands execute operations on domain model Queries arbitrary views of data
  15. Interesting Links 1. 2. 3. 4. 5. 6. 7. 8.

    9. Pure Function (Wikipedia) Referenctial Transparency (Wikipedia) Persistent Data Structure (Wikipedia) Presistend Data Structures and Managed References ADT, Product and Sum Types (Bob Harper, PFPL) Simple Made Easy (Rich Hickey) Function Composition (Wikipedia) Building Apps w/ Functional Domain Models (Debasish Ghosh) CQRS and EventSourcing (Daniel Westheide)
  16. Thanks for your attention