Who am I?
⢠Yoshitaka Fujii
⢠@yoshiyoshifujii
⢠Joined MOTEX in April, 2014
⢠Web Application Engineer
⢠Scala (7 months)âš
Java, Python
èªå·±ç޹ä»ããšã ãªãŒããã¯ã¹æ ªåŒäŒç€ŸãScalaæŽ7ã¶æã
5.
We are lookingfor
a Scala of Engineers !!
Scalaãšã³ãžãã¢åéäž!!
Point of LayeredArchitecture
1. To clarify the responsibilities of the layer
2. Depends only on the lower layer
3. Isolating the Domain
ã¬ã€ã€ãŒã®è²¬åãæç¢ºã«ããããšãäžäœã¬ã€ã€ãŒã ãã«äŸåã
ãããšããã¡ã€ã³ãéé¢ããããšã
24.
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.
ãŠãŒã¶ã«æ å ±ã衚瀺ããããŠãŒã¶ããã®ã³ãã³ããè§£éããã
å€éšã¢ã¯ã¿ã¯å¥ã®ã³ã³ãã¥ãŒã¿ã·ã¹ãã ã®ããšãããã
Domain Layer
⢠Conceptsof the business.
⢠Information about the business solution.
⢠Business rules.
⢠This layer is the beat of business software.
ããžãã¹ã®æŠå¿µãããžãã¹ã眮ãããç¶æ³ã«é¢ããæ å ±ãããž
ãã¹ã«ãŒã«ãããžãã¹ãœãããŠã§ã¢ã®æ žå¿ã
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
32.
Form
⢠So-called Form
â¢It express POST data from view.
⢠Making corresponding to each View.
ããããFormãViewããã®POST/PUTããŒã¿ã衚ãã
33.
case class XxxForm(email:String, name: String)
def form(): Form[XxxForm] =
Form(
mapping(
"email" -> email,
"name" -> nonEmptyText(maxLength = 80))
(XxxForm.apply)(XxxForm.unapply))
case class XxxForm(email:String, name: String)
case class XxxViewModel(email: String, name: String)
def convertForm2ViewModel(form: XxxForm):
XxxViewModel =
XxxViewModel(
form.email,
form.name)
36.
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
37.
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
38.
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
When we implemented,
theresponsibilities started
to leak across
the boundaries.
å®è£ ããŠã¿ããšã責åã®å¢çããæ··ããããã«ãªããŸããã
To clarify theresponsibilities
of the layer
⢠Communication
⢠Review
⢠Analysis Modeling
ã¬ã€ã€ãŒã®è²¬åãæ··ãããªããããã³ãã¥ãã±ãŒã·ã§ã³ãš
Reviewãšåæã¢ããªã³ã°ã掻çšããã
Responsibility of Service
â¢Once, approach to Application Service.
⢠Temporarily forgive the outï¬ow of Domain
logic.
⢠Repeat to consider refactoring.
Application Serviceã«å¯ãããDomainããžãã¯ã®æµåºãäžæ
çã«èš±å®¹ãRefactoringãç¹°ãè¿ãæ€èšã
CQRS
⢠CQRS standsfor âš
Command Query Responsibility Segregation
⢠First proposed by Greg Young
⢠Martin Fowler
http://martinfowler.com/bliki/CQRS.html
Greg Youngãæå±ããã®ãMartin Fowlerãããã°ã§ç޹ä»ã
ãã
81.
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
ããããã¡ãœããã¯ããã³ãã³ãããããã¯ãã¯ãšãªãã®ãã
ããäžæ¹ã§ããã®äž¡æ¹ã¯ãã¡ã
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
User Interface ApplicationDomain Infrastructure
ViewModelForm
Record
SQL
JSON
Result SetForm =>
ViewModel
ViewModel
=> SQL
ResultSet =>
Record
QueryModel
=> JSON
Record =>
QueryModel
QueryModel
90.
Query Model
⢠QueryModel 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!!
User Interface ApplicationDomain Infrastructure
ViewModelForm Entity
Record
SQL
JSON Entity
Result Set
ViewModel
Form =>
ViewModel
ViewModel
=> Entity
Entity => SQL
ResultSet =>
Record
Record =>
Entity
Entity =>
ViewModel
ViewModel
=> JSON
Summary of is-aRoot Entity
⢠Service specifying the children
⢠To clarify the hierarchy
⢠It eliminates redundant processing
Serviceãåãç¥ã£ãŠãããã¿ãŒã³ãæ¡çš
sealed abstract classValidation[+E, +A]
ï¬nal case class Success[A](a: A)
extends Validation[Nothing, A]
ï¬nal case class Failure[E](e: E)
extends Validation[E, Nothing]
143.
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))
}
144.
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