Heads-on Domain
Driven Development
in Scala
Yoshitaka Fujii
@yoshiyoshifujii
2016 ScalaMatsuri
Scalaでドメむン駆動蚭蚈に真正面から取り組んだ話
Who am I ?
• Yoshitaka Fujii
• @yoshiyoshifujii
• Joined MOTEX in April, 2014
• Web Application Engineer
• Scala (7 months)‹
Java, Python
自己玹介。゚ムオヌテックス株匏䌚瀟。Scalaæ­Ž7ヶ月。
We are looking for
a Scala of Engineers !!
Scala゚ンゞニア募集䞭!!
Isn't it difficult?
難しくないですか ?
Design
approach
蚭蚈手法に過ぎない。
and
Design
Pattern
あず、デザむンパタヌン
Let’s implement !!
さあ、実装しよう!!
https://goo.gl/DQB6Ak
too difficult 

難しい 
Today’s
topic
今日、お話したいこず
Amateur
Team
ScalaもDDDも経隓の無い私たちのチヌムが
Hard
Fighting
日々悩み悪戊苊闘した内容に぀いお
I'd like to share
what we
learned!!
同じような悩みを持぀皆様の䞀助になればうれしく思いたす。
Agenda
• Layered Architecture
• CQRS
• is-a Root Entity
• Message
アゞェンダです。
Layered Architecture
レむダヌ化アヌキテクチャに぀いお
Reprinted from Eric Evans (2003, pp.68) Domain Driven Design.
Review
おさらい
Point of‹
Layered Architecture
レむダヌ化アヌキテクチャの芁玄。
Point of Layered Architecture
1. To clarify the responsibilities of the layer
2. Depends only on the lower layer
3. Isolating the Domain
レむダヌの責務を明確にするこず。䞋䜍レむダヌだけに䟝存す
るこず。ドメむンを隔離するこず。
User Interface Layer
• Showing information to the user.
• Interpreting the user’s commands.
• The external actor might sometimes be
another computer system rather than a
human user.
ナヌザに情報を衚瀺する。ナヌザからのコマンドを解釈する。
倖郚アクタは別のコンピュヌタシステムのこずもある。
Application Layer
• Defines the jobs the software.
• Directs the expressive domain objects to work
our problems.
• This layer is kept thin.
• It does not contain business rules or
knowledge.
゜フトりェアの仕事を定矩、ドメむンオブゞェクの問題解決を
導く。薄く保぀。ビゞネスルヌルや知識を含たない。
Domain Layer
• Concepts of the business.
• Information about the business solution.
• Business rules.
• This layer is the beat of business software.
ビゞネスの抂念。ビゞネスが眮かれた状況に関する情報。ビゞ
ネスルヌル。ビゞネス゜フトりェアの栞心。
Infrastructure Layer
• Provides generic technical capabilities that
support the higher layers.
• Message sending for the application.
• Persistence for the domain.
• Drawing widgets for the UI
䞊䜍レむダを支える技術的機胜を提䟛。Applicationのための
メッセヌゞ送信。Domainのための氞続化。UIの描画。
First wall
最初の壁
https://goo.gl/ErmMRx
We wondered how the
tasks within a layer
can be implemented...
どのようにレむダヌの責務を実装しようか 
User Interface Application Domain Infrastructure
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form
• So-called Form
• It express POST data from view.
• Making corresponding to each View.
いわゆるForm。ViewからのPOST/PUTデヌタを衚す。
case class XxxForm(email: String, name: String)
def form(): Form[XxxForm] =
Form(
mapping(
"email" -> email,
"name" -> nonEmptyText(maxLength = 80))
(XxxForm.apply)(XxxForm.unapply))
ViewModel
• Synonymous with the MVVM pattern
• Holding a state for drawing a view.
• Form => Application => Domain
MVVMパタヌンのViewModelず同矩。Viewを描画するための
状態の保持。UI=>Application=>Domainず受け枡す。
case class XxxForm(email: String, name: String)
case class XxxViewModel(email: String, name: String)
def convertForm2ViewModel(form: XxxForm):
XxxViewModel =
XxxViewModel(
form.email,
form.name)
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
So we tried, but...
ず、いうこずですが 
Second wall
次の壁
https://goo.gl/ErmMRx
When we implemented,
the responsibilities started
to leak across
the boundaries.
実装しおみるず、責務の境界が、混じるようになりたした。
User Interface
x‹
Domain
たずえば、User Interface に Domain が。
def xxxForm(id: Option[Long]): Form[XxxForm] = Form(
mapping(
"name" -> nonEmptyText(maxLength = 128)
.verifying(“error.uniqueness.name",
!service.isSameNameExisting(_, id)),
"path" -> nonEmptyText(maxLength = 128),
"lockVersion" -> optional(longNumber))
(XxxForm.apply)(XxxForm.unapply))
Application
x
Domain
たずえば、Application に Domain が。
private def validateExists(vm: ViewModel):
Either[Error, ViewModel] = {
repository.findBy(vm.email) match {
case Some(_) => Left("not exists!")
case None => Right(vm)
}
}
Need a plan to make the
boundaries more clear
境界を芋倱わないための工倫が必芁。
Thinking

どのようにレむダヌの責務を実装しようか 
Communication
コミュニケヌション
Review
レビュヌ
Analysis Modeling
分析モデリング
To clarify the responsibilities
of the layer
• Communication
• Review
• Analysis Modeling
レむダヌの責務が混じらないよう、コミュニケヌションず
Reviewず分析モデリングを掻甚した。
Third wall
次の壁
https://goo.gl/ErmMRx
Those pesky Services
曲者のService。
Service
of three types
3぀のService
Partitioning Services into Layers
• Application Service
• Domain Service
• Infrastructure Service
アプリケヌション局、ドメむン局、むンフラ局のそれぞれにサ
ヌビスっおありたすよね。
Reprinted from Eric Evans (2003, pp.107) Domain Driven Design.
How do we know which
service to use when?
どう責務を䜿い分けおいたす?
Overuse of Services leads
to leakage of Domain
knowledge to other layers.
Serviceを倚甚するずDomainロゞックが流出しがち。
Thinking

3぀のServiceをどのように扱うか 
Responsibility of Service
• Once, approach to Application Service.
• Temporarily forgive the outflow of Domain
logic.
• Repeat to consider refactoring.
Application Serviceに寄せる。Domainロゞックの流出を䞀時
的に蚱容。Refactoringを繰り返し怜蚎。
Refactoring
リファクタリング
Scrum
スクラム
Day of Refactoring
リファクタリングをする日
STOP knowledge leaks
• Refactoring
• Scrum
• Day of Refactoring
ドメむンの知識の流出を、リファクタリング、スクラム、リフ
ァクタリングする日を䜿っお継続的に改善した。
Forth wall
次の壁
https://goo.gl/ErmMRx
too many conversion logics
コンバヌト凊理が倚いですよね?
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
1 2 3
4567
7 conversions
just for a roundtrip
いっお、かえっおするだけなのに、7回も 
Just live with it!!
仕方ない!
Some sacrifices
are unavoidable
to isolate the Domains.
Domainを隔離するためなら、倚少の犠牲はやむを埗ない!!
Domain isolation = DDD !!
Domainを隔離するこずが、DDDだ!!
Conversion makes the
Domain boundaries clear
Convertするこずで、Domainの境界も分かりやすい
Responsibility is
easy to understand
in isolation.
責務が分離され、分かりやすい
Still, too many
conversions...
ずはいえ、Convert凊理倚いよなヌ
Command
Query
Responsibility
Segregation
コマンドク゚リ責務分離
Agenda
• Layered Architecture
• CQRS
• is-a Root Entity
• Message
CQRS
CQRS
• CQRS stands for ‹
Command Query Responsibility Segregation
• First proposed by Greg Young
• Martin Fowler
http://martinfowler.com/bliki/CQRS.html
Greg Youngが提唱したのをMartin Fowlerがブログで玹介し
た。
About CQRS
• CQS (Command query separation)
• It states that every method should either be a
command that performs an action
• or a query that returns data to the caller
• but not both
あらゆるメ゜ッドは、「コマンド」もしくは「ク゚リ」のいず
れか䞀方で、その䞡方はダメ。
In the first place

そもそも 
Tackling Complexity
in the Heart of Software
゜フトりェアの耇雑さに立ち向かう
View the list
䞀芧を衚瀺する
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
more complexity ?
耇雑にしおない?
Query Model
呌び出し元にデヌタを戻す「ク゚リ」に぀いお。
User Interface Application Domain Infrastructure
ViewModelForm
Record
SQL
JSON
Result SetForm =>
ViewModel
ViewModel
=> SQL
ResultSet =>
Record
QueryModel
=> JSON
Record =>
QueryModel
QueryModel
Query Model
• Query Model into the Infrastructure Layer
• Application Layer direct connection to
Infrastructure Layer
• Result Set => Record => Query Model
• Query Model is returned to User Interface
Layer
Infrastructure局にQuery Modelを䜜る。 Application局から盎接
Infrastructure局。 Query ModelはUser Interface局たで持ち蟌みOK!!
Command Model
䜕らかのアクションを実行する「コマンド」に぀いお。
User Interface Application Domain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
Command Model
is simple
Layered Architecture
Command Model は埓来のレむダヌ化アヌキテクチャ
Many of
the business logic
is Command.
ビゞネスロゞックの倚くはCommand
Command tends to be
smaller than Query
Command Modelがシステムの占める割合は少なめ
Summary of CQRS
• Simple retrieval process is separated into
queries.
• Direct connection to the Infrastructure Layer.
• Simple things made simply.
単玔な取埗凊理はク゚リずしお分離。盎接むンフラ局にアクセ
ス。シンプルなものはシンプルに䜜る。
Agenda
• Layered Architecture
• CQRS
• is-a Root Entity
• Message
ROOT゚ンティティがis-aの関連を持っおいる堎合
is-a Root Entity
ROOT゚ンティティがis-aの関連を持っおいる堎合
Root Entity
has
is-a
Root Entityをis-aの関連ずする蚭蚈にするこずっおありたすよ
ね
is-a
is confusing
is-aの関連をRoot Entityにするずややこしい。
One Repository ?
or
Two Repository ?
Repositoryは、1぀2぀
Should the parent track the
children?
芪が子をしっおいるの
Awkward in terms of OO
オブゞェクト指向的に倉
Should the Service specify
the children?
クラむアントが子を指定するの
Awkward in terms of the
aggregation
集玄の抂念的に倉
Take a look
at the source code
コヌドで芋おみる
trait RootEntity {
val id: Option[Long]
val name: String
}
case class Sub1(
id: Option[Long], name: String)
extends RootEntity
case class Sub2(
id: Option[Long], name: String)
extends RootEntity
Parent tracking the children
集玄の芪が子を知っおいるパタヌン
trait RootEntityRepository {
object Sub1Repository { def save(entity: Sub1): Option[Sub1] = ??? }
object Sub2Repository { def save(entity: Sub2): Option[Sub2] = ??? }
def save(types: String, entity: RootEntity) = {
types match {
case "Sub1" => Sub1Repository.save(entity)
case "Sub2" => Sub2Repository.save(entity)
case _ => None
}
}
}
object RootEntityRepository extends RootEntityRepository
trait Service {
def createSub1 = {
val sub1 = Sub1(None, "sub1")
RootEntityRepository.save("Sub1", sub1)
}
def createSub2 = {
val sub2 = Sub2(None, "sub2")
RootEntityRepository.save("Sub2", sub2)
}
}
Service specifying the
children
サヌビスが子を指定するパタヌン
trait RootEntityRepository[E <: RootEntity] {}
trait Sub1Repository {}
trait Sub2Repository {}
object Sub1Repository
extends RootEntityRepository[Sub1]
with Sub1Repository
object Sub2Repository
extends RootEntityRepository[Sub2]
with Sub2Repository
trait Service {
def createSub1 = {
val sub1 = Sub1(None, "sub1")
Sub1Repository.save(sub1)
}
def createSub2 = {
val sub2 = Sub2(None, "sub2")
Sub2Repository.save(sub2)
}
}
Which pattern is
more suitable...
どっちのケヌスが適しおいるか 
To clarify the hierarchy
どのピラルキヌに属するRepositoryか明瀺する。
trait RootEntityRepository[E <: RootEntity] {}
trait Sub1Repository {}
trait Sub2Repository {}
object Sub1Repository
extends RootEntityRepository[Sub1]
with Sub1Repository
object Sub2Repository
extends RootEntityRepository[Sub2]
with Sub2Repository
It eliminates
redundant processing
冗長な凊理を簡略化する。
trait RootEntityRepository {
object Sub1Repository { def save(entity: Sub1): Option[Sub1] = ??? }
object Sub2Repository { def save(entity: Sub2): Option[Sub2] = ??? }
def save(types: String, entity: RootEntity) = {
types match {
case "Sub1" => Sub1Repository.save(entity)
case "Sub2" => Sub2Repository.save(entity)
case _ => None
}
}
}
object RootEntityRepository extends RootEntityRepository
Summary of is-a Root Entity
• Service specifying the children
• To clarify the hierarchy
• It eliminates redundant processing
Serviceが子を知っおいるパタヌンを採甚
Agenda
• Layered Architecture
• Dependency Injection
• is-a Root Entity
• CQRS
• Message
最埌にMessageに぀いお。
Message
Low Layer
浅いレむダヌの゚ラヌメッセヌゞはUIに盎接返せる
Deep Layer
深いレむダヌの゚ラヌメッセヌゞはそう簡単じゃない
Infrastructure Layer
むンフラ局
Unrecoverable
Exception
埩旧䞍可胜な䟋倖
Domain Layer
ドメむン局
I want to return
a message
on the screen
なんらかのメッセヌゞを返したい
Type of Message
• Option
• Either
• Try
• Validation
Option
• Some or None. Why None ?
• None is Exception
• Exception is Exception
SomeかNoneで、なぜNoneか分からない。Noneがそもそも
異垞なこずもある。その堎合は䟋倖にしたい。
Either
• Left or Right. Left is error message.
• Monad (salaz)
• Single message only
Left or RightでLeftにメッセヌゞが詰められる。Monadなコ
ヌディング可胜。ただしメッセヌゞは1぀。
Try
• Define the type of Exception
• Simple error handling
• Throw to the higher layer
䟋倖の型を定矩。throw圢匏で゚ラヌ時の制埡が容易。凊理を
䞭断し䞊䜍のレむダヌたで到達可胜。
Validation (Scalaz)
• Return the stack error
• But not Monad
• not be used in for-yield
• Applicative
゚ラヌを詰めお返すこずが可胜。Monadではない。for匏で䜿
えない。Applicative。
Stack ?
or not
゚ラヌ時のメッセヌゞをStackしたいか、したくないか。
Validation
したいならValidation。
or not
Try (or Either)
したくないならTry (or Either)
But 

ただし 
Validation is
Applicative.
not Monad.
ValidationはApplicativeであり、Monadではないよね。
sealed abstract class Validation[+E, +A]
final case class Success[A](a: A)
extends Validation[Nothing, A]
final case class Failure[E](e: E)
extends Validation[E, Nothing]
def ap[EE >: E, B](x: => Validation[EE, A => B])
(implicit E: Semigroup[EE]): Validation[EE, B] = (this, x)
match {
case (Success(a), Success(f)) => Success(f(a))
case (e @ Failure(_), Success(_)) => e
case (Success(f), e @ Failure(_)) => e
case (Failure(e1), Failure(e2)) => Failure(E.append(e2, e1))
}
case class Person(name: String, age: Int)
def validateName(name: String) =
if (name.length > 1) name.successNel
else "invalid name".failureNel
def validateAge(age: Int) =
if (age >= 0) age.successNel
else "invalid age".failureNel
scala> (validateName("Yoshida") |@| validateAge(27))
(Person)
res0: scalaz.Validation[scalaz.NonEmptyList[String],Person]
= Success(Person(Yoshida,27))
scala> (validateName("") |@| validateAge(-1))(Person)
res1: scalaz.Validation[scalaz.NonEmptyList[String],Person]
= Failure(NonEmptyList(invalid name, invalid age))
Summary of Message
• Unrecoverable exception
• Domain Layer return a message to screen
• Validation or Try or Either
埩旧䞍可胜な䟋倖もあるが、ドメむン局から䜕らかのメッセヌ
ゞを返したいずき、ValidationずTry(or Either)を䜿い分け。
Summary
たずめ
Scala
Scalaで悪戊苊闘
Scala x DDD
ScalaずDDDでさらに苊悩
We hope this was
helpful to you!!
同じような悩みを持぀皆様の䞀助になればうれしく思いたす。
Thank you for
your attention.
ご枅聎ありがずうございたした。

ScalaMatsuri 2016