SlideShare a Scribd company logo
1 of 42
Download to read offline
Behind OOD
// domain modelling in a post-OO world
Ruslan Shevchenko
Lynx Capital Partners
https://github.com/rssh
@rssh1
Domain modelling
• Representation of business domain objects:
• in ‘head’ of people
• in code
Domain modelling.
• Outline typical OOD issues
• Build
• simple domain model for toy billing system.
// scala, can be mapped to java.
• internal DSL
Domain modelling
• Traditional OO way: have layer of classes,
which corresponds to domain objects.
• Extensibility via inheritance in some
consistent Universal Ontology
• Intensional Equality [identity != attribute]
• Object instance <=> Entity in real world
Traditional OO WAY
• Human is an upright, featherless biped with
broad, flat nails.
Traditional OO WAY
• Human is an upright, featherless biped with
broad, flat nails.
Open for extensions close for modifications
Traditional OO WAY
• Human is an upright, featherless biped with
broad, flat nails.
Open for extensions close for modifications
Traditional OO WAY
• Intensional Equality [ mutability ]
// same identity thought lifecycle
Traditional OO WAY
• Object in code <=> Object in real world
class Person {
int getId();
String getName();
int getAge();
Set<Person> getChilds()
}
— thread-safe ?
— persistent updates ?
Domain modelling
• Traditional OO way: have layer of classes,
which corresponds to domain objects.
• Extensibility via inheritance in some
consistent Universal Ontology
• Intensional Equality [identity != attribute]
• Object instance <=> Entity in real world
Domain modelling
• Traditional OO way: similar to early
philosophy
• Very general
• Idealistic
• Fit to concrete cases may be undefined
Domain modelling
• Post OO way: describe limited set of objects
and relationships.
• Algebra instead Ontology
• Existential equality [identity == same
attributes]
• Rules of algebra <=> rules of reality.
Domain modelling: where to start.
• Example: description of small billing system
Subscriber
Billing System
Service PaymentPlanuse
in accordance
with
Service is Internet | Telephony
PaymentPlan is Monthly Fee for Quantity Limit and
Overhead cost per Unit
Unit Internet is Gbin
Telephony is Minute
and Bandwidth
TariffPlan: Use limit and quantity from service.
sealed trait Service
{
type Limits
def quantity(l:Limits): BigDecimal
}
case object Internet extends Service
{
case class Limits(gb:Int,bandwidth:Int)
def quantity(l:Limits) = l.gb
}
case object Telephony extends Service
{
type Limits = Int
def quantity(l) = l
TariffPlan: Price per limit and charge
case class TariffPlan[Limits](
monthlyFee: BigDecimal,
monthlyLimits: Limits,
excessCharge: BigDecimal
)
Subscriber ? Service ?
case class Subscriber( id, name, … )
trait BillingService
{
def checkServiceAccess(u:Subscriber,s:Service):Boolean
def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber
def ratePeriod(u:Subscriber, date: DateTime)
def acceptPayment(u:Subscriber, payment: Payment)
}
// Aggregate
// let’s add to Subscriber all fields, what needed.
adding fields for Subscriber aggregates.
case class Subscriber(id, name,
serviceInfos:Map[Service,SubscriberServiceInfo],
account: BigDecimal, …..
)
case class SubscriberServiceInfo[S<:Service,L<:S#Limits](
service: S, tariffPlan: tariffPlan[S,L], amountUsed:Double
)
trait BillingService
{
def checkServiceAccess(u:Subscriber,s:Service):Boolean =
u.serviceInfos(s).isDefined && u.account > 0
}
adding fields for Subscriber aggregates.
case class Subscriber(id, name,
serviceInfos:Map[Service,SubscriberServiceInfo[_,_]],
account: BigDecimal, …..
)
case class ServiceUsage(service, amount, when)
trait BillingService
{
def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber =
serviceInfo(r.service) match {
case Some(SubscriberServiceInfo(service,plan,amount)) =>
val price = ….
u.copy(account = u.account - price,
serviceInfo = serviceInfo.updated(s,
}
adding fields for Subscriber aggregates.
trait BillingService
{
def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber =
serviceInfo(r.service) match {
case Some(SubscriberServiceInfo(service,plan,amount)) =>
val price = ….
u.copy(account = u.account - price,
serviceInfo = serviceInfo.updated(s,
ServiceInfo(service,plan,amount+r.amount))
)
case None =>
throw new IllegalStateException(“service is not enabled”)
}
…………….
}
Subscriber aggregates [rate: lastPayedDate]
case class Subscriber(id, name,
serviceInfos:Map[Service,SubscriberServiceInfo[_,_]],
account: BigDecimal,
lastPayedDate: DateTime
)
trait BillingService
{
def ratePeriod(u:Subscriber,date:DateTime):Subscriber =
if (date < u.lastPayedDate) u
else {
val price = …..
subscriber.copy(account = u.account - price,
lastPayedDate = date+1.month)
}
}
Subscriber:
case class Subscriber(
id : Long,
name: String,
serviceInfos:Map[Service,SubscriberServiceInfo[_,_]],
account: BigDecimal,
lastPayedDate: DateTime
)
case class SubscriberServiceInfo[S<:Service,L<:S#Limits](
service: S,
tariffPlan: tariffPlan[L],
amountUsed:Double
)
Subscriber:
case class Subscriber(
id : Long,
name: String,
internetServiceInfo: ServiceInfo[Internet,Internet.Limits],
telephonyServiceInfo: ServiceInfo[Telephony,Telephony.Limits],
account: BigDecimal,
lastPayedDate: DateTime
) {
def serviceInfo(s:Service):SubscriberServiceInfo[s.type,s.Limits] =
….
def updateServiceInfo[S<:Service,L<:S#Limits](
serviceInfo:SubscriberServiceInfo[S,L]): Subscriber =
…
}
From domain model to implementation. [S1]
Subscriber
Service TariffPlan
Domain Data/ Aggregates Services
SubscriberOperations
TariffPlanOperations
….
Repository
DD — contains only essential data
Services — only functionality
Testable.
No mess with implementation.
Service calls — domain events
From domain model to implementation. [S1]
Improvements/Refactoring space:
• Errors handling
• Deaggregate
• Fluent DSL
Errors handling (design for failure)
trait BillingService
{
def checkServiceAccess(u:Subscriber,s:Service):Boolean
def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber
def ratePeriod(u:Subscriber, date: DateTime): Subscriber
def acceptPayment(u:Subscriber, payment:Payment):Subscriber
}
Design for failure:
trait BillingService
{
def checkServiceAccess(u:Subscriber,s:Service): Boolean
def rateServiceUsage(u:Subscriber,r:ServiceUsage):Try[Subscriber]
def ratePeriod(u:Subscriber, date: DateTime): Try[Subscriber]
def acceptPayment(u:Subscriber, payment:Payment): Subscriber
}
Design for failure:
sealed trait Try[+X]
case class Success[X](v:X) extends Try[X]
case class Failure(ex:Throwable) extends Try[Nothing]
when use Try / traditional exception handling?
Try — error recovery is a part of business layers.
(i.e. errors is domain-related)
Exception handling — error recovery is a part of infrastructure layer.
(i. e. errors is system-related)
Deaggregation:
trait Repository
{
def create[T](): T
def find[T](id: Id[T]): Try[T]
def save[T](obj: T): Try[Boolean]
}
Deaggregation:
trait Repository
{
def create[T](): T
def find[T](id: Id[T]): Try[T]
def save[T](obj: T) : Try[T]
………..
def subscriberServiceInfo[S<:Service,L<:S#Limits]
(id: Id[Subscriber], s:S): SubscriberServiceInfo[S,L]
def updateSubsriberServiceInfo[S<:Service,L<:S#Limits] (
id: Id[Subscriber],s:S,si:SubscriberServiceInfo[S,L]):
Try[SubscriberServiceInfo[S,L]]
}
Deaggregation:
trait BillingService
{
def checkServiceAccess(r:Repository, uid:Id[Subscriber],
s:Service): Boolean
def rateServiceUsage(r: Repository, uid:Id[Subscriber],
r:ServiceUsage):Try[Subscriber]
…..
}
Deaggregation:
trait BillingService
{
val repository: Repository
def checkServiceAccess(uid:Id[Subscriber], s:Service): Try[Boolean]
def rateServiceUsage(uid:Id[Subscriber], r:ServiceUsage):Try[Subscriber]
…..
}
// BillingService operations interpret repository
Deaggregation. [S2]
Subscriber
Service TariffPlan
Domain Data/ Aggregates Services
SubscriberOperations
TariffPlanOperations
….
Repository
Interpret
- Not for all cases
- Loss
- generality of repository
- simply logic
- Gain
- simple repository operations
- more efficient data access.
DSL: Domain Specific Language.
Idea: fluent syntax for fluent operations.
• Syntax sugar, can be used by non-programmers
• ‘Micro-interpreter/compiler’
• Internal/External
Let’s build simple Internal DSL for our tariff plans.
TariffPlan: DSL
case class TariffPlan[Limits](
monthlyFee: BigDecimal,
monthlyLimits: Limits,
excessCharge: BigDecimal
)
TariffPlan(100,Limits(1,100),2)
TariffPlan(montlyFee=100,
Internet.Limits(gb=1,bandwidth=100),
2)
100 hrn montly (1 gb) speed 100 excess 2 hrn per 1 gb
// let’s build
TariffPlan: DSL
(100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb)
trait TariffPlanDSL[S <: Service, L <: S#Limits] {
implicit class ToHrn(v: Int)
{
def hrn = this
def monthly(x: LimitExpression) =
TariffPlan(v, x.limit, 0)
def per(x: QuantityExpression
}
1 hrn = 1.hrn =
new ToHrn(1).hrn
trait LimitExpression{
def limit: L
}
type QuantityExpression
{
def quantity: Int
}
TariffPlan: DSL
(100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb)
object InternetTariffPlanDSL extends TariffPlanDSL[Internet.type, Internet.Limits]
implicit class Gb(v: Int) extends LimitExpression with QuantityExpression{
def gb = this
def limit = Internet.Limits(v,100)
def quantity = x
}
TariffPlan: DSL
(100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb)
(100 hrn) montly (1 gb) == (100.hrn).montly(1.gb)
TariffPlan: DSL
(100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb))
trait TariffPlanDSL[S,L]
case class PerExpression(money: ToHrn, quantity: QuantityExpression)
trait RichTariffPlan(p: TariffPlan[L]) {
def excess(x: PerExpression) = p.copy(excessCost=x.v)
}
((100.hrn).montly(1.gb) speed 100).excess((2 hrn) per (1 gb))
TariffPlan: DSL
(100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb))
object InternetTariffPlanDSL[S,L]
trait RichTariffPlan(p: TariffPlan[L]) extends super.RichTariffPlan(p) {
def speed(x: Int) = p.copy(
monthlyLimits = p.monthlyLimits.copy(
bandwidth = x)
)
}
((100.hrn).montly(1.gb) speed 100).excess ((2.hrn).per(1.gb))
((100.hrn).montly(1.gb).speed(100)).excess ((2.hrn).per(1.gb))
DSL: (100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb))
Internal
External
Need some boilerplate code.
Useful when developers need fluent business
domain object notation.
Internally - combination of builder and interpreter patterns
Useful when external users (non-developers) want to describe
domain objects.
Internally - language-mini-interpreter.
// [scala default library include parser combinators]
Post-OOD domain modelling
Domain Data Objects
‘OO’ Objects with behavior
• Closed world.
• Different lifecycle can be described by
different types
• Composition over inheritance
Domain Services
• Open world.
• No data, only functionality. Calls can be replayed.
• Traditional inheritance
Infrastructure Services
• Interpreters of ‘domain services’ functions
// phantom types.
Thanks for attention.
Fully - implemented ‘tiny’ domain model and DSL:
https://github.com/rssh/scala-training-materials/tree/master/fwdays2015-examples/
Ruslan Shevchenko
Lynx Capital Partners
https://github.com/rssh
@rssh1

More Related Content

Similar to Modeling a Billing Domain in a Post-OO World

"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан..."После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...Fwdays
 
Visual basic intoduction
Visual basic intoductionVisual basic intoduction
Visual basic intoductionSpy Seat
 
Programming Languages: some news for the last N years
Programming Languages: some news for the last N yearsProgramming Languages: some news for the last N years
Programming Languages: some news for the last N yearsRuslan Shevchenko
 
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced FeaturesAndrew Liu
 
MongoDB Stich Overview
MongoDB Stich OverviewMongoDB Stich Overview
MongoDB Stich OverviewMongoDB
 
The Yin and Yang of Software
The Yin and Yang of SoftwareThe Yin and Yang of Software
The Yin and Yang of Softwareelliando dias
 
Strata Software Architecture NY: The Data Dichotomy
Strata Software Architecture NY: The Data DichotomyStrata Software Architecture NY: The Data Dichotomy
Strata Software Architecture NY: The Data DichotomyBen Stopford
 
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...confluent
 
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...Data Con LA
 
Dubbo and Weidian's practice on micro-service architecture
Dubbo and Weidian's practice on micro-service architectureDubbo and Weidian's practice on micro-service architecture
Dubbo and Weidian's practice on micro-service architectureHuxing Zhang
 
Scaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and DevicesScaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and DevicesRick Warren
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxSumant Tambe
 
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...Flink Forward
 
Developing Dynamic Reports for TMS Using Crystal Reports
Developing Dynamic Reports for TMS Using Crystal ReportsDeveloping Dynamic Reports for TMS Using Crystal Reports
Developing Dynamic Reports for TMS Using Crystal ReportsChad Petrovay
 
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDB
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDBIntroducing MongoDB Stitch, Backend-as-a-Service from MongoDB
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDBMongoDB
 
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMVoxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMManuel Bernhardt
 
Event Driven Services Part 1: The Data Dichotomy
Event Driven Services Part 1: The Data Dichotomy Event Driven Services Part 1: The Data Dichotomy
Event Driven Services Part 1: The Data Dichotomy Ben Stopford
 
The Data Dichotomy- Rethinking the Way We Treat Data and Services
The Data Dichotomy- Rethinking the Way We Treat Data and ServicesThe Data Dichotomy- Rethinking the Way We Treat Data and Services
The Data Dichotomy- Rethinking the Way We Treat Data and Servicesconfluent
 
introduction to Windows Comunication Foundation
introduction to Windows Comunication Foundationintroduction to Windows Comunication Foundation
introduction to Windows Comunication Foundationredaxe12
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoJAXLondon2014
 

Similar to Modeling a Billing Domain in a Post-OO World (20)

"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан..."После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
"После OOD: как моделировать предметную область в пост-объектном мире" Руслан...
 
Visual basic intoduction
Visual basic intoductionVisual basic intoduction
Visual basic intoduction
 
Programming Languages: some news for the last N years
Programming Languages: some news for the last N yearsProgramming Languages: some news for the last N years
Programming Languages: some news for the last N years
 
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features
[PASS Summit 2016] Azure DocumentDB: A Deep Dive into Advanced Features
 
MongoDB Stich Overview
MongoDB Stich OverviewMongoDB Stich Overview
MongoDB Stich Overview
 
The Yin and Yang of Software
The Yin and Yang of SoftwareThe Yin and Yang of Software
The Yin and Yang of Software
 
Strata Software Architecture NY: The Data Dichotomy
Strata Software Architecture NY: The Data DichotomyStrata Software Architecture NY: The Data Dichotomy
Strata Software Architecture NY: The Data Dichotomy
 
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...
Kafka Summit NYC 2017 - The Data Dichotomy: Rethinking Data and Services with...
 
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...
Big Data Day LA 2016/ Data Science Track - Enabling Cross-Screen Advertising ...
 
Dubbo and Weidian's practice on micro-service architecture
Dubbo and Weidian's practice on micro-service architectureDubbo and Weidian's practice on micro-service architecture
Dubbo and Weidian's practice on micro-service architecture
 
Scaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and DevicesScaling DDS to Millions of Computers and Devices
Scaling DDS to Millions of Computers and Devices
 
Reactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and RxReactive Stream Processing Using DDS and Rx
Reactive Stream Processing Using DDS and Rx
 
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...
Introducing BinarySortedMultiMap - A new Flink state primitive to boost your ...
 
Developing Dynamic Reports for TMS Using Crystal Reports
Developing Dynamic Reports for TMS Using Crystal ReportsDeveloping Dynamic Reports for TMS Using Crystal Reports
Developing Dynamic Reports for TMS Using Crystal Reports
 
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDB
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDBIntroducing MongoDB Stitch, Backend-as-a-Service from MongoDB
Introducing MongoDB Stitch, Backend-as-a-Service from MongoDB
 
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVMVoxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
Voxxed Days Vienna - The Why and How of Reactive Web-Applications on the JVM
 
Event Driven Services Part 1: The Data Dichotomy
Event Driven Services Part 1: The Data Dichotomy Event Driven Services Part 1: The Data Dichotomy
Event Driven Services Part 1: The Data Dichotomy
 
The Data Dichotomy- Rethinking the Way We Treat Data and Services
The Data Dichotomy- Rethinking the Way We Treat Data and ServicesThe Data Dichotomy- Rethinking the Way We Treat Data and Services
The Data Dichotomy- Rethinking the Way We Treat Data and Services
 
introduction to Windows Comunication Foundation
introduction to Windows Comunication Foundationintroduction to Windows Comunication Foundation
introduction to Windows Comunication Foundation
 
Crafted Design - Sandro Mancuso
Crafted Design - Sandro MancusoCrafted Design - Sandro Mancuso
Crafted Design - Sandro Mancuso
 

More from Ruslan Shevchenko

Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Ruslan Shevchenko
 
Papers We Love / Kyiv : PAXOS (and little about other consensuses )
Papers We Love / Kyiv :  PAXOS (and little about other consensuses )Papers We Love / Kyiv :  PAXOS (and little about other consensuses )
Papers We Love / Kyiv : PAXOS (and little about other consensuses )Ruslan Shevchenko
 
Scala / Technology evolution
Scala  / Technology evolutionScala  / Technology evolution
Scala / Technology evolutionRuslan Shevchenko
 
{co/contr} variance from LSP
{co/contr} variance  from LSP{co/contr} variance  from LSP
{co/contr} variance from LSPRuslan Shevchenko
 
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Ruslan Shevchenko
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.Ruslan Shevchenko
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scalaRuslan Shevchenko
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisRuslan Shevchenko
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applicationsRuslan Shevchenko
 
Jslab rssh: JS as language platform
Jslab rssh:  JS as language platformJslab rssh:  JS as language platform
Jslab rssh: JS as language platformRuslan Shevchenko
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation streamRuslan Shevchenko
 
Web architecture - overview of techniques.
Web architecture - overview of  techniques.Web architecture - overview of  techniques.
Web architecture - overview of techniques.Ruslan Shevchenko
 

More from Ruslan Shevchenko (20)

Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]Embedding Generic Monadic Transformer into Scala. [Tfp2022]
Embedding Generic Monadic Transformer into Scala. [Tfp2022]
 
Svitla talks 2021_03_25
Svitla talks 2021_03_25Svitla talks 2021_03_25
Svitla talks 2021_03_25
 
Akka / Lts behavior
Akka / Lts behaviorAkka / Lts behavior
Akka / Lts behavior
 
Papers We Love / Kyiv : PAXOS (and little about other consensuses )
Papers We Love / Kyiv :  PAXOS (and little about other consensuses )Papers We Love / Kyiv :  PAXOS (and little about other consensuses )
Papers We Love / Kyiv : PAXOS (and little about other consensuses )
 
Scala / Technology evolution
Scala  / Technology evolutionScala  / Technology evolution
Scala / Technology evolution
 
{co/contr} variance from LSP
{co/contr} variance  from LSP{co/contr} variance  from LSP
{co/contr} variance from LSP
 
N flavors of streaming
N flavors of streamingN flavors of streaming
N flavors of streaming
 
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
Scala-Gopher: CSP-style programming techniques with idiomatic Scala.
 
SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.SE 20016 - programming languages landscape.
SE 20016 - programming languages landscape.
 
Few simple-type-tricks in scala
Few simple-type-tricks in scalaFew simple-type-tricks in scala
Few simple-type-tricks in scala
 
Why scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with thisWhy scala is not my ideal language and what I can do with this
Why scala is not my ideal language and what I can do with this
 
Scala jargon cheatsheet
Scala jargon cheatsheetScala jargon cheatsheet
Scala jargon cheatsheet
 
Java & low latency applications
Java & low latency applicationsJava & low latency applications
Java & low latency applications
 
Csp scala wixmeetup2016
Csp scala wixmeetup2016Csp scala wixmeetup2016
Csp scala wixmeetup2016
 
IDLs
IDLsIDLs
IDLs
 
R ext world/ useR! Kiev
R ext world/ useR!  KievR ext world/ useR!  Kiev
R ext world/ useR! Kiev
 
Jslab rssh: JS as language platform
Jslab rssh:  JS as language platformJslab rssh:  JS as language platform
Jslab rssh: JS as language platform
 
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
JDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation streamJDays Lviv 2014:  Java8 vs Scala:  Difference points & innovation stream
JDays Lviv 2014: Java8 vs Scala: Difference points & innovation stream
 
Web architecture - overview of techniques.
Web architecture - overview of  techniques.Web architecture - overview of  techniques.
Web architecture - overview of techniques.
 
R scala 17_05_2014
R scala 17_05_2014R scala 17_05_2014
R scala 17_05_2014
 

Recently uploaded

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
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Andreas Granig
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEEVICTOR MAESTRE RAMIREZ
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio, Inc.
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Matt Ray
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfFerryKemperman
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentationvaddepallysandeep122
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceBrainSell Technologies
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
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
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 

Recently uploaded (20)

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
 
Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024Automate your Kamailio Test Calls - Kamailio World 2024
Automate your Kamailio Test Calls - Kamailio World 2024
 
Cloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEECloud Data Center Network Construction - IEEE
Cloud Data Center Network Construction - IEEE
 
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
 
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
 
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed DataAlluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
Alluxio Monthly Webinar | Cloud-Native Model Training on Distributed Data
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
Open Source Summit NA 2024: Open Source Cloud Costs - OpenCost's Impact on En...
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Introduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdfIntroduction Computer Science - Software Design.pdf
Introduction Computer Science - Software Design.pdf
 
PREDICTING RIVER WATER QUALITY ppt presentation
PREDICTING  RIVER  WATER QUALITY  ppt presentationPREDICTING  RIVER  WATER QUALITY  ppt presentation
PREDICTING RIVER WATER QUALITY ppt presentation
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
CRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. SalesforceCRM Contender Series: HubSpot vs. Salesforce
CRM Contender Series: HubSpot vs. Salesforce
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
Advantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your BusinessAdvantages of Odoo ERP 17 for Your Business
Advantages of Odoo ERP 17 for Your Business
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
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
 
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 

Modeling a Billing Domain in a Post-OO World

  • 1. Behind OOD // domain modelling in a post-OO world Ruslan Shevchenko Lynx Capital Partners https://github.com/rssh @rssh1
  • 2. Domain modelling • Representation of business domain objects: • in ‘head’ of people • in code
  • 3. Domain modelling. • Outline typical OOD issues • Build • simple domain model for toy billing system. // scala, can be mapped to java. • internal DSL
  • 4. Domain modelling • Traditional OO way: have layer of classes, which corresponds to domain objects. • Extensibility via inheritance in some consistent Universal Ontology • Intensional Equality [identity != attribute] • Object instance <=> Entity in real world
  • 5. Traditional OO WAY • Human is an upright, featherless biped with broad, flat nails.
  • 6. Traditional OO WAY • Human is an upright, featherless biped with broad, flat nails. Open for extensions close for modifications
  • 7. Traditional OO WAY • Human is an upright, featherless biped with broad, flat nails. Open for extensions close for modifications
  • 8. Traditional OO WAY • Intensional Equality [ mutability ] // same identity thought lifecycle
  • 9. Traditional OO WAY • Object in code <=> Object in real world class Person { int getId(); String getName(); int getAge(); Set<Person> getChilds() } — thread-safe ? — persistent updates ?
  • 10. Domain modelling • Traditional OO way: have layer of classes, which corresponds to domain objects. • Extensibility via inheritance in some consistent Universal Ontology • Intensional Equality [identity != attribute] • Object instance <=> Entity in real world
  • 11. Domain modelling • Traditional OO way: similar to early philosophy • Very general • Idealistic • Fit to concrete cases may be undefined
  • 12. Domain modelling • Post OO way: describe limited set of objects and relationships. • Algebra instead Ontology • Existential equality [identity == same attributes] • Rules of algebra <=> rules of reality.
  • 13. Domain modelling: where to start. • Example: description of small billing system Subscriber Billing System Service PaymentPlanuse in accordance with Service is Internet | Telephony PaymentPlan is Monthly Fee for Quantity Limit and Overhead cost per Unit Unit Internet is Gbin Telephony is Minute and Bandwidth
  • 14. TariffPlan: Use limit and quantity from service. sealed trait Service { type Limits def quantity(l:Limits): BigDecimal } case object Internet extends Service { case class Limits(gb:Int,bandwidth:Int) def quantity(l:Limits) = l.gb } case object Telephony extends Service { type Limits = Int def quantity(l) = l
  • 15. TariffPlan: Price per limit and charge case class TariffPlan[Limits]( monthlyFee: BigDecimal, monthlyLimits: Limits, excessCharge: BigDecimal )
  • 16. Subscriber ? Service ? case class Subscriber( id, name, … ) trait BillingService { def checkServiceAccess(u:Subscriber,s:Service):Boolean def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber def ratePeriod(u:Subscriber, date: DateTime) def acceptPayment(u:Subscriber, payment: Payment) } // Aggregate // let’s add to Subscriber all fields, what needed.
  • 17. adding fields for Subscriber aggregates. case class Subscriber(id, name, serviceInfos:Map[Service,SubscriberServiceInfo], account: BigDecimal, ….. ) case class SubscriberServiceInfo[S<:Service,L<:S#Limits]( service: S, tariffPlan: tariffPlan[S,L], amountUsed:Double ) trait BillingService { def checkServiceAccess(u:Subscriber,s:Service):Boolean = u.serviceInfos(s).isDefined && u.account > 0 }
  • 18. adding fields for Subscriber aggregates. case class Subscriber(id, name, serviceInfos:Map[Service,SubscriberServiceInfo[_,_]], account: BigDecimal, ….. ) case class ServiceUsage(service, amount, when) trait BillingService { def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber = serviceInfo(r.service) match { case Some(SubscriberServiceInfo(service,plan,amount)) => val price = …. u.copy(account = u.account - price, serviceInfo = serviceInfo.updated(s, }
  • 19. adding fields for Subscriber aggregates. trait BillingService { def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber = serviceInfo(r.service) match { case Some(SubscriberServiceInfo(service,plan,amount)) => val price = …. u.copy(account = u.account - price, serviceInfo = serviceInfo.updated(s, ServiceInfo(service,plan,amount+r.amount)) ) case None => throw new IllegalStateException(“service is not enabled”) } ……………. }
  • 20. Subscriber aggregates [rate: lastPayedDate] case class Subscriber(id, name, serviceInfos:Map[Service,SubscriberServiceInfo[_,_]], account: BigDecimal, lastPayedDate: DateTime ) trait BillingService { def ratePeriod(u:Subscriber,date:DateTime):Subscriber = if (date < u.lastPayedDate) u else { val price = ….. subscriber.copy(account = u.account - price, lastPayedDate = date+1.month) } }
  • 21. Subscriber: case class Subscriber( id : Long, name: String, serviceInfos:Map[Service,SubscriberServiceInfo[_,_]], account: BigDecimal, lastPayedDate: DateTime ) case class SubscriberServiceInfo[S<:Service,L<:S#Limits]( service: S, tariffPlan: tariffPlan[L], amountUsed:Double )
  • 22. Subscriber: case class Subscriber( id : Long, name: String, internetServiceInfo: ServiceInfo[Internet,Internet.Limits], telephonyServiceInfo: ServiceInfo[Telephony,Telephony.Limits], account: BigDecimal, lastPayedDate: DateTime ) { def serviceInfo(s:Service):SubscriberServiceInfo[s.type,s.Limits] = …. def updateServiceInfo[S<:Service,L<:S#Limits]( serviceInfo:SubscriberServiceInfo[S,L]): Subscriber = … }
  • 23. From domain model to implementation. [S1] Subscriber Service TariffPlan Domain Data/ Aggregates Services SubscriberOperations TariffPlanOperations …. Repository DD — contains only essential data Services — only functionality Testable. No mess with implementation. Service calls — domain events
  • 24. From domain model to implementation. [S1] Improvements/Refactoring space: • Errors handling • Deaggregate • Fluent DSL
  • 25. Errors handling (design for failure) trait BillingService { def checkServiceAccess(u:Subscriber,s:Service):Boolean def rateServiceUsage(u:Subscriber,r:ServiceUsage):Subscriber def ratePeriod(u:Subscriber, date: DateTime): Subscriber def acceptPayment(u:Subscriber, payment:Payment):Subscriber }
  • 26. Design for failure: trait BillingService { def checkServiceAccess(u:Subscriber,s:Service): Boolean def rateServiceUsage(u:Subscriber,r:ServiceUsage):Try[Subscriber] def ratePeriod(u:Subscriber, date: DateTime): Try[Subscriber] def acceptPayment(u:Subscriber, payment:Payment): Subscriber }
  • 27. Design for failure: sealed trait Try[+X] case class Success[X](v:X) extends Try[X] case class Failure(ex:Throwable) extends Try[Nothing] when use Try / traditional exception handling? Try — error recovery is a part of business layers. (i.e. errors is domain-related) Exception handling — error recovery is a part of infrastructure layer. (i. e. errors is system-related)
  • 28. Deaggregation: trait Repository { def create[T](): T def find[T](id: Id[T]): Try[T] def save[T](obj: T): Try[Boolean] }
  • 29. Deaggregation: trait Repository { def create[T](): T def find[T](id: Id[T]): Try[T] def save[T](obj: T) : Try[T] ……….. def subscriberServiceInfo[S<:Service,L<:S#Limits] (id: Id[Subscriber], s:S): SubscriberServiceInfo[S,L] def updateSubsriberServiceInfo[S<:Service,L<:S#Limits] ( id: Id[Subscriber],s:S,si:SubscriberServiceInfo[S,L]): Try[SubscriberServiceInfo[S,L]] }
  • 30. Deaggregation: trait BillingService { def checkServiceAccess(r:Repository, uid:Id[Subscriber], s:Service): Boolean def rateServiceUsage(r: Repository, uid:Id[Subscriber], r:ServiceUsage):Try[Subscriber] ….. }
  • 31. Deaggregation: trait BillingService { val repository: Repository def checkServiceAccess(uid:Id[Subscriber], s:Service): Try[Boolean] def rateServiceUsage(uid:Id[Subscriber], r:ServiceUsage):Try[Subscriber] ….. } // BillingService operations interpret repository
  • 32. Deaggregation. [S2] Subscriber Service TariffPlan Domain Data/ Aggregates Services SubscriberOperations TariffPlanOperations …. Repository Interpret - Not for all cases - Loss - generality of repository - simply logic - Gain - simple repository operations - more efficient data access.
  • 33. DSL: Domain Specific Language. Idea: fluent syntax for fluent operations. • Syntax sugar, can be used by non-programmers • ‘Micro-interpreter/compiler’ • Internal/External Let’s build simple Internal DSL for our tariff plans.
  • 34. TariffPlan: DSL case class TariffPlan[Limits]( monthlyFee: BigDecimal, monthlyLimits: Limits, excessCharge: BigDecimal ) TariffPlan(100,Limits(1,100),2) TariffPlan(montlyFee=100, Internet.Limits(gb=1,bandwidth=100), 2) 100 hrn montly (1 gb) speed 100 excess 2 hrn per 1 gb // let’s build
  • 35. TariffPlan: DSL (100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb) trait TariffPlanDSL[S <: Service, L <: S#Limits] { implicit class ToHrn(v: Int) { def hrn = this def monthly(x: LimitExpression) = TariffPlan(v, x.limit, 0) def per(x: QuantityExpression } 1 hrn = 1.hrn = new ToHrn(1).hrn trait LimitExpression{ def limit: L } type QuantityExpression { def quantity: Int }
  • 36. TariffPlan: DSL (100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb) object InternetTariffPlanDSL extends TariffPlanDSL[Internet.type, Internet.Limits] implicit class Gb(v: Int) extends LimitExpression with QuantityExpression{ def gb = this def limit = Internet.Limits(v,100) def quantity = x }
  • 37. TariffPlan: DSL (100 hrn) montly (1 gb) speed 100 excess (2 hrn) per (1 gb) (100 hrn) montly (1 gb) == (100.hrn).montly(1.gb)
  • 38. TariffPlan: DSL (100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb)) trait TariffPlanDSL[S,L] case class PerExpression(money: ToHrn, quantity: QuantityExpression) trait RichTariffPlan(p: TariffPlan[L]) { def excess(x: PerExpression) = p.copy(excessCost=x.v) } ((100.hrn).montly(1.gb) speed 100).excess((2 hrn) per (1 gb))
  • 39. TariffPlan: DSL (100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb)) object InternetTariffPlanDSL[S,L] trait RichTariffPlan(p: TariffPlan[L]) extends super.RichTariffPlan(p) { def speed(x: Int) = p.copy( monthlyLimits = p.monthlyLimits.copy( bandwidth = x) ) } ((100.hrn).montly(1.gb) speed 100).excess ((2.hrn).per(1.gb)) ((100.hrn).montly(1.gb).speed(100)).excess ((2.hrn).per(1.gb))
  • 40. DSL: (100 hrn) montly (1 gb) speed 100 excess ((2 hrn) per (1 gb)) Internal External Need some boilerplate code. Useful when developers need fluent business domain object notation. Internally - combination of builder and interpreter patterns Useful when external users (non-developers) want to describe domain objects. Internally - language-mini-interpreter. // [scala default library include parser combinators]
  • 41. Post-OOD domain modelling Domain Data Objects ‘OO’ Objects with behavior • Closed world. • Different lifecycle can be described by different types • Composition over inheritance Domain Services • Open world. • No data, only functionality. Calls can be replayed. • Traditional inheritance Infrastructure Services • Interpreters of ‘domain services’ functions // phantom types.
  • 42. Thanks for attention. Fully - implemented ‘tiny’ domain model and DSL: https://github.com/rssh/scala-training-materials/tree/master/fwdays2015-examples/ Ruslan Shevchenko Lynx Capital Partners https://github.com/rssh @rssh1