Slide 1

Slide 1 text

DDD + Clean Architecture ʴϢʔεέʔεۦಈ։ൃͷྑ͍ͱ͜ΖΛऔΓೖΕΑ͏ 2016/03/16 @yoskhdia DDD+CQRS+EventSourcing࣮૷͢Δձ

Slide 2

Slide 2 text

About me • ԞాՂڗʢYoshitaka Okudaʣ • גࣜձࣾSocketʢKDDI Syn.ϗʔϧσΟϯάεάϧʔϓʣ
 ΞʔΩςΫτ • Twitter @yoskhdia • interested in DDD/Scala/C#/Reactive System/
 Architect/System Thinking/Team Building/
 Agile/ܦӦ৘ใֶ/On-Road Bike

Slide 3

Slide 3 text

Agenda • υϝΠϯۦಈઃܭʢDDDʣ͓͞Β͍ • Clean Architectureͱ͸Կ͔ • DDD + Clean Architectureମݧஊ • Ϣʔεέʔεۦಈ։ൃʢICONIXϓϩηεʣʹ ग़ձͬͨ࿩

Slide 4

Slide 4 text

ཹҙࣄ߲ • ͜ͷൃද͸ࢲݸਓͷݟղʹدΔ΋ͷͰ͢ɻ • ॻ੶ʮυϝΠϯۦಈઃܭʯ΋ਖ਼ࣜʹ͸ʮΤϦοΫɾΤϰΝϯ εͷʯͱ෇͘Α͏ʹɺDDD͸ϕετϓϥΫςΟεΛ·ͱΊͨ ஌ࣝମܥͰ͋Γɺઈରͷਖ਼ղͷ͋Δ΋ͷͰ͸͋Γ·ͤΜɻ • ࠾༻͢ΔϓϩμΫτͷੑ֨ʹΑͬͯɺ۩ମతͳํ๏͸มΘΓ ·͢ɻʢࠓճ͸UIΛ࣋ͨͳ͍APIͰߟ͍͑ͯ·͢ɻʣ • ͦͷͨΊɺ͜͏͍͏෩ʹద༻͍ͯ͠Δਓ΋͍ΔΜͩͳɺͱ͍ ͏Թ͔͍৺Ͱ͓ئ͍͍ͨ͠·͢...

Slide 5

Slide 5 text

υϝΠϯۦಈઃܭʢDDDʣ ͓͞Β͍ ίΞυϝΠϯ ϢϏΩλεݴޠ ϞσϧΛ୳ٻ

Slide 6

Slide 6 text

ͬ͘͟ΓDDD • υϝΠϯۦಈઃܭ͸ݴ༿Λେ੾ʹ͢Δ։ൃख๏ • ΤΫετϦʔϜϓϩάϥϛϯάʢXPʣΛϕʔ εʹϞσϧۦಈઃܭΞϓϩʔνΛద༻͍ͯ͠Δ • νʔϜͷڌΓॴͱͳΓಘΔ • ໎ͬͨΒಡΉ

Slide 7

Slide 7 text

ݴ༿ͷఆٛʢݪଇʣ • υϝΠϯʢDomainʣ • Ϗδωεશମͷ໰୊ྖҬͦͷ΋ͷͷ͜ͱɻιϑτ΢ΣΞͰղܾ͢Δͷ͸ɺ͜ͷҰ෦ɻ • υϝΠϯϞσϧʢDomain Modelʣ • υϝΠϯʹରͯ͠ɺͦͷղܾࡦʢιϦϡʔγϣϯʣΛϞσϧԽͨ͠΋ͷɻ • υϝΠϯΤΩεύʔτʢDomain Expertʣ • υϝΠϯʹਫ਼௨͍ͯ͠ΔਓɻҰਓͰ͋Δ͜ͱ΋͋Ε͹ෳ਺ਓͰ͋Δ͜ͱ΋͋Δɻ • ίΞυϝΠϯʢCore Domainʣ • υϝΠϯ͸͍͔ͭ͘ͷྖҬʹ෼ׂ͢Δ͜ͱ͕ଟ͍ɻ͜ͷ࣌ɺҰ൪ϏδωεՁ஋ͷߴ͍ྖ ҬΛίΞυϝΠϯͱ͍͏ɻ࣌ؒ΍ਓ͸༗ݶͳͷͰίΞυϝΠϯΛݟ͚ͭͯɺͦ͜ʹ஫ྗ ͢Δ͜ͱ͕ॏཁɻ

Slide 8

Slide 8 text

ݴ༿ͷఆٛʢݪଇʣ • ϢϏΩλεݴޠʢUbiquitous Languageʣ • ίʔυΛॻ͍͍ͯΔͱΦϨΦϨ໋໊Λ͕ͪ͠ɻ͢ΔͱɺυϝΠϯΤΩεύʔτ ͱ࿩Λ͢Δͱ͖ʹݴ༿ͷ຋༁͕ൃੜ͢Δɻ͜͏ͳΔͱɺυϝΠϯΤΩεύʔτ ͷඳ͘Ϟσϧͱίʔυ͕ဃ཭͍ͯͬͯ͠͠·͏ͷͰɺυϝΠϯΤΩεύʔτΛ ؚΉνʔϜશମͰಉ͡ݴ༿Λ࢖͏Α͏ʹ߹ҙ͢Δɻ • ڥք͚ͮΒΕͨίϯςΩετʢBounded Contextʣ • จ຺ʢίϯςΩετʣʹΑͬͯɺಉ͡ݴ༿ͳͷʹҟͳΔҙຯʹͳΔ͜ͱ͕͋Δɻ υϝΠϯϞσϧ͸େ͖͘ͳΓ͕ͪͳͷͰɺҰ؏ੑΛอͬͨ··εέʔϧ͢Δʹ ͸ɺίϯςΩετͷڥքΛϋοΩϦͤͯ͞ҙຯͷมΘΒͳ͍৔ॴΛ࡞Δɻίϯ ςΩετϚοϓͱ͍͏πʔϧΛ࢖ͬͨΓ͢Δɻ
 InfoQʮίϯςΩετϚοϐϯάʹΑΔઓུతυϝΠϯۦಈઃܭʯΛࢀর

Slide 9

Slide 9 text

υϝΠϯͱίϯςΩετͷؔ܎ υϝΠϯ ίϯςΩετ αϒυϝΠϯ ίΞυϝΠϯ • ఺ઢɿ
 υϝΠϯڥք • ੺࣮ઢɿ
 ίϯςΩετڥք • ίϯςΩετ͸͍ ͔ͭ͘ͷυϝΠϯ ڥքʹލΔ͜ͱ͕ ͋Δ • ཧ૝͸αϒυϝΠ ϯͱίϯςΩετ ͕1ର1 αϒυϝΠϯ

Slide 10

Slide 10 text

ଓ͖͸ࢀߟࢿྉͰ

Slide 11

Slide 11 text

DDDΛ΍Δҙٛ • υϝΠϯϞσϧ͕ચ࿅͞Ε͍ͯ͘͜ͱͰɺ • ʮۀ຿஌ࣝʯ-ʮݴ༿ʯ-ʮίʔυʯ͕࿈ಈ • ֎͔ΒͷมԽʹదԠ͠΍͘͢ • ։ൃΛਐΊΔ͜ͱʹΑͬͯൃݟ͞ΕΔ৽ͨͳ ஌ݟΛϏδωε΁ؐݩ

Slide 12

Slide 12 text

–Jim HighsmithࢯʮWhat is Agility?ʯ “ΞδϟΠϧ͞ͱ͸ɺܹม͢ΔϏδωε؀ ڥʹ͓͍ͯརӹΛੜΈग़ͨ͢ΊʹɺมԽ ʹରԠ͢Δͱಉ࣌ʹɺมԽΛ࡞Γग़͢ೳ ྗͰ͋Δɻ”

Slide 13

Slide 13 text

ͦΕΛ࣮ફ͢ΔͨΊͷDDD υϝΠϯϞσϦϯάΛ௨ͯ͡ ։ൃऀ͕Ϗδωεʹد༩͢Δ

Slide 14

Slide 14 text

Clean Architectureͱ͸Կ͔ γεςϜʹߏ଄Λ༩͑ ґଘؔ܎نଇΛఆٛ͢Δ

Slide 15

Slide 15 text

ଞͷΞʔΩςΫνϟ -BZFSFE"SDIJUFDUVSF ૚Ͱ෼཭ Πϯϑϥʹґଘ )FYBHPOBM"SDIJUFDUVSF ΠϯϑϥΛ֎෦Խ "EBQUFSͰܨ͙ 0OJPO"SDIJUFDUVSF "QQMJDBUJPO Λ૚Խ

Slide 16

Slide 16 text

͍ͣΕ΋ ιϑτ΢ΣΞΛ෼ׂ͠ ߏ଄Λ໌֬ʹ͢Δ ͭ·Γɺؔ৺ࣄͷ෼཭

Slide 17

Slide 17 text

Clean Architecture ΋ͦͷҰ೿

Slide 18

Slide 18 text

CMPHUIMJHIUDPNVODMFCPCUIF DMFBOBSDIJUFDUVSFIUNM

Slide 19

Slide 19 text

Hexagonal΍Onionͱૂ͍͸ಉ͡ • ϑϨʔϜϫʔΫͱ͍͏੍໿ʹγεςϜΛ٧ΊࠐΉͷ Ͱ͸ͳ͘ɺγεςϜʹϑϨʔϜϫʔΫΛ౰ͯ͸ΊΔ • ϑϨʔϜϫʔΫ͔Βಠཱ͢Δ ㅟ ㅟ ㅟ ㅟ • UI͔Βಠཱ͢Δ ㅟ ㅟ ㅟ ㅟ • σʔλϕʔε͔Βಠཱ͢Δ ㅟ ㅟ ㅟ ㅟ • ೚ҙͷ֎෦ϦιʔεɺαʔϏε͔Βಠཱ͢Δ ㅟ ㅟ ㅟ ㅟ

Slide 20

Slide 20 text

%PNBJO૚ اۀશମͷϏδωεϧʔϧ ΛΧϓηϧԽ 6TF$BTF૚ ΞϓϦέʔγϣϯͷ ϏδωεϧʔϧΛΧϓηϧԽ "EBQUFS૚ ಺ͱ֎ͷσʔλͷม׵͕ओ 'SBNFXPSL%SJWFS૚ ۩ମతͳπʔϧ

Slide 21

Slide 21 text

ཁࢫ • ඇৗʹγϯϓϧͳϧʔϧͳͷͰ෼͔Γ΍͍͢ • ૚Ͱ෼཭ • େ੾ͳ΋ͷΛ಺ଆʹஔ͘ • ґଘؔ܎نଇʢ಺ଆʹͷΈґଘʣΛकΔ • ಠཱੑ͸ςετͷ༰қੑʹ΋ߩݙ͢Δ • ٕज़͕ݹ͘ͳͬͨΒ࠷খݶͷखؒͰަ׵Ͱ͖Δ • ϑϨʔϜϫʔΫΛަ׵͢Δ͜ͱ͸͋ͬͯ΋ɺυϝΠϯ஌ࣝΛަ׵ ͢Δͱ͍͏ͷ͸͋Γಘͳ͍

Slide 22

Slide 22 text

ઃܭͷϙΠϯτɿڥքͷԣஅ • ԁͷํʹ໨͕ߦ͖͕͚ͪͩΕͲɺઃܭͷ͏ ͑Ͱ͸͕ͬͪ͜ॏཁ • ௨ৗɺController͔Βೖ͖ͬͯͯPresenter ʹग़ͯߦ͘ྲྀΕ • UseCase͸֎૚Λ஌Βͳ͍ͷͰɺग़ྗΛฦ ͢ʹ͸ґଘؔ܎ٯసͷݪଇΛ࢖͍ͬͯΔ
 ʢDependency Inversion Principleʣ • ૚ͷڥքΛอͪͳ͕ΒॲཧϑϩʔΛ࣮ݱ ৄࡉ͸ޙ΄Ͳ

Slide 23

Slide 23 text

DDD + Clean Architecture ମݧஊ Clean Architecture͸෼͔Γ΍͍͢ DDDͷ࣮ફ͸νʔϜͰόϥϯεΛߟ͑Δ

Slide 24

Slide 24 text

࣮૷αϯϓϧ
 github.com/yoskhdia/ cleanArchSample

Slide 25

Slide 25 text

ύοέʔδߏ੒ • Domain(Entities)૚ • Contract૚ • Domain૚ͱͷڮ౉͠
 ʢDIΛ࢖͏ͷͰΠϯλϑΣʔε͸ผʹ͍ͯ͠Δʣ • UseCase૚ • Adapter૚ • Repositoryͷ࣮૷Ϋϥε΋͜͜ • ʢExternal૚ʣ • ϑϨʔϜϫʔΫ΍ϥΠϒϥϦͷ૚ͱ͍͏Ґஔ͚ͮ ̐૚Ͱͳͯ͘΋0,

Slide 26

Slide 26 text

Domain(Entities)૚ • POSO(Plain Old Scala Object)͕جຊ • ϑϨʔϜϫʔΫ΁ͷґଘ͚ͩͰͳ͘ɺϥΠϒ ϥϦ΁ͷґଘ΋ۃྗগͳ͘ • ࠓͷͱ͜ΖJoda-TimeͷΈʢJava8 Date and Time API΁ͷҠߦ͸ݕ౼தʣ

Slide 27

Slide 27 text

Contract/UseCase૚ *OQVU1PSUͷ࣮૷͸ 6TF$BTF͕ߦ͏ ґଘؔ܎ٯసͷݪଇͰ6TF$BTF ͸0VUQVU1PSUʹग़ྗΛ౉͚ͩ͢ ʹ૚͕ด͡ΒΕΔ 0VUQVU1PSUͷ࣮૷͸ 1SFTFOUFS͕ߦ͏

Slide 28

Slide 28 text

Use Case import scala.concurrent.{ExecutionContext, Future}
 
 trait UseCase {
 type In
 
 type Out
 
 protected def call(arg: In)(implicit ec: ExecutionContext): Future[Out]
 } "EBQUFS૚ͱͷ࿈ܞ͸1PSUʹҕৡ

Slide 29

Slide 29 text

Input Port import scala.concurrent.ExecutionContext
 import scala.util.{Failure, Success}
 trait PushPort[Arg, Result] {
 self: UseCase =>
 
 override final type In = Arg
 
 override final type Out = Result
 
 def execute[T <: Callback[Result]](arg: Arg)(callback: T)
 (implicit ec: ExecutionContext): Unit = {
 call(arg).onComplete {
 case Success(result) =>
 callback.onSuccess(result)
 case Failure(t) =>
 callback.onFailure(t)
 }
 }
 } "EBQUFS૚͔ΒͲ͏໯͏͔ ԿΛฦ͔͢Λఆٛ *OQVU1PSUͷ໾ׂ͸ ड͚औΔ͜ͱ·ͰͳͷͰ 6OJUΛฦ͢

Slide 30

Slide 30 text

Output Port trait Callback[Result] {
 
 def onSuccess(result: Result): Unit
 
 def onFailure(t: Throwable): Unit
 } ΞϓϦέʔγϣϯϩδοΫͷΤϥʔ΋ ಛผͳ&YDFQUJPOΛ༻ҙͯ͠ฦ͢Α͏ʹ͍ͯ͠Δ ʢ+BWBͷ׳शʹ͍ۙʣ ※Callback vs Promise(Future)͸Full൛Ͱิ଍

Slide 31

Slide 31 text

Clean ArchitectureΛ ద༻͢ΔͨΊͷิॿ͸͜Ε͚ͩ

Slide 32

Slide 32 text

Use Caseͷఆٛ package contract.usecase
 
 import contract.{PushPort, UseCase}
 import domain.{GroupId, UserId}
 
 trait PickLeaderUseCase extends UseCase with PushPort[GroupId, UserId] ࣮͸αϘ͍ͬͯΔ 6TF$BTF૚Ͱѻ͍΍͍͢ ΦϒδΣΫτ %50 ʹ͢Δ

Slide 33

Slide 33 text

Use Caseͷ࣮૷ package usecase
 
 import javax.inject.Inject
 import contract.usecase.PickLeaderUseCase
 import domain.UserRepository
 
 import scala.concurrent.{ExecutionContext, Future}
 
 class PickLeaderUseCaseImpl @Inject()(userRepository: UserRepository) extends PickLeaderUseCase {
 
 override protected def call(groupId: In) (implicit ec: ExecutionContext): Future[Out] = {
 userRepository.findBy(groupId).map { board =>
 board.pickLeader // ୭ΛͲ͏Ϧʔμʹ͢Δ͔͸υϝΠϯ஌ࣝ
 }
 }
 } ΠϯλϑΣʔεΛ࢖͏ %*ͰґଘΛ୯ํ޲ʹ

Slide 34

Slide 34 text

Adapter૚ 3FQPTJUPSZͷ࣮૷Ϋϥε΋ ͜ͷ૚ͷத 42-ఆٛͳͲ ֎͔ΒͷೖྗΛ ಺ଆͷΦϒδΣΫτʹม׵ ྫɿ1045͞Εͨσʔλ ಺͔Βͷग़ྗΛ ֎ଆͷσʔλʹม׵ ྫɿ+40/

Slide 35

Slide 35 text

Controller import contract.usecase.PickLeaderUseCase
 import domain.GroupId
 import play.api.data._
 import play.api.libs.concurrent.Execution.Implicits.defaultContext
 import play.api.mvc.{Action, Controller}
 
 class GroupController @Inject() (useCase: PickLeaderUseCase, presenter: PickedLeaderPresenter) extends Controller { 
 val form: Form[GroupId] = ??? // ׂѪ
 def pickLeader = Action.async { implicit request =>
 form.bindFromRequest.fold(_ => Future.successful(BadRequest("…")), (groupId: GroupId) =>
 presenter.response(useCase.execute(groupId))
 )
 }
 } ͜ͷॻ͖ํʹ͍ͭͯ͸'VMM൛Ͱิ଍ ೖྗσʔλ͔Βͷม׵͕੹຿

Slide 36

Slide 36 text

Presenter import contract.callback.PickedLeaderCallback
 import domain.UserId
 import play.api.libs.json.Json
 import scala.concurrent.{ExecutionContext, Future, Promise}
 
 class PickedLeaderPresenter extends Presenter[PickedLeaderCallback] {
 
 implicit val writer = Json.writes[UserId]
 
 override def response(call: UseCaseExecutor) (implicit ec: ExecutionContext): Future[Rendered] = {
 val callback = new CallbackImpl
 call(callback)
 callback.promise.future.map { userId =>
 Ok(Json.toJson(userId))
 }
 }
 } ग़ྗσʔλ΁ͷม׵͕੹຿

Slide 37

Slide 37 text

ControllerͰPresenterͷ໾ׂΛ ݉೚ͯ͠΋ྑ͍ͷͰ͸ʁ • ࠓճͷΑ͏ͳখن໛ͳ΋ͷͩͱɺͻͱͭͷΫϥ εʹશ෦ॻ͍ͯ͠·͍ͨ͘ͳΔ • ໾ׂͷҟͳΔ΋ͷΛҰͭͷΫϥεʹೖΕΔͷ ͸୯Ұ੹೚ͷݪଇʹ൓͢Δ • Controller͸ೖྗͷม׵ɺPresenter͸ग़ྗͷ ม׵ʹઐ೦͢Δ͜ͱͰංେԽ͕๷͛Δʢίʔ υ͸੒௕͢Δʣ

Slide 38

Slide 38 text

ϓϩμΫτͰͷऔΓ૊Έ

Slide 39

Slide 39 text

୊ࡐ֓ཁ • ϑϩϯτͱAjaxͰ΍ΓऔΓ͢ΔAPIαʔϏε • ݱߦͰ͸RailsͰ࡞ΒΕ͍ͯͯɺࠓճ͸ϦϓϨʔε • ࢓༷͸ݱߦ౿ऻ • Ϟσϧ͸ActiveRecord͔Β୤٫ • Scala + Play! Framework • ߴෛՙ • ग़དྷΔݶΓ1౓ͷϦΫΤετʹ͓͞Ί͍ͨ • σʔλετΞͳͲ֎෦Ϧιʔε΁ͷΞΫηε͕ूத @@'MJQEFTL@@

Slide 40

Slide 40 text

DDD + Clean ArchitectureͰ σʔλΞΫηεΛίϯτϩʔϧ༰қʹ • DDDʹै͏ͱRepositoryΛ࢖͏ݸॴ͸ΞϓϦέʔγϣ ϯαʔϏεʢUseCaseʣ͔υϝΠϯαʔϏεʹݶఆ͞ Ε͍ͯ͘ • ू໿(Aggregate)͕ϥΠϑαΠΫϧ·Ͱ୲͏ͱ੹຿ ͕େ͖͘ͳΓ͗͢ΔʢIDDD p.254ʣ • ࣗવͱσʔλΞΫηεݸॴ͕෼͔Γ΍͘͢ ※υϝΠϯαʔϏεɿෳ਺ͷΤϯςΟςΟʹ·͕ͨΔৼΔ෣͍ͳͲɺΤϯςΟςΟ͕ ࣋ͭʹ͸ద͞ͳ͍ৼΔ෣͍Λఆٛͨ͠υϝΠϯΦϒδΣΫτ

Slide 41

Slide 41 text

DDD + Clean ArchitectureͰ σʔλΞΫηεΛίϯτϩʔϧ༰қʹ • ࠓͷͱ͜ΖυϝΠϯαʔϏεͰRepositoryΛ࢖͍͍ͨέʔε͸ग़͍ͯ ͳ͍ͷͰɺUseCaseͰͷΈRepositoryΛ࢖͑ΔΑ͏ʹͯ͠ࢼ͍ͯ͠Δ • ҙਤͤͣԿ౓΋ݺͼग़ͯ͠͠·͏Մೳੑ͕͋Δˍ࢖͑Δঢ়ଶͩͱ࢖ ͍ͨ͘ͳΔͷ͕ਓ৘ͳͷͰActiveRecordͷೋͷ෣͍ʹͳΒͳ͍Α͏ ஫ҙΛ෷͍ͬͯΔ • ґଘؔ܎نଇʹΑͬͯ૚͕ด͡ΒΕ͍ͯΔͷͰɺͲ͜ͰσʔλΞΫ ηε͍ͯ͠Δ͔෼͔Γ΍͘͢ͳͬͨ • σʔλετΞ͕Ұ൪֎ͳͷͰަ׵͕͠΍͘͢ͳͬͨɻElasticsearch ൛ͱDynamo൛ͰύϑΥʔϚϯεൺֱ͔ͯ͠Β࠾༻ΛܾΊΔ౳Մೳ

Slide 42

Slide 42 text

೉͍͠఺ • υϝΠϯΦϒδΣΫτΛUseCaseͰ༻ҙͯ͠ࢦࣔΛग़͢ ඞཁ͕͋ΔͷͰɺจ຺ͱͯࣗ͠વͳͷ͔ɺೲಘͰ͖Δ͔ Λ܁Γฦ͠ߟ͑Δඞཁ͕͋Δɻ • υϝΠϯαʔϏεࣗମ͕ͦ΋ͦ΋ۃྗ࢖Θͳ͍ํ͕ྑ ͍΋ͷͰ͸͋Δ͚ΕͲɺෳ਺ͷΤϯςΟςΟʹؔ܎͢ ΔΑ͏ͳৼΔ෣͍͸υϝΠϯαʔϏεͷํ͕ࣗવɻ • ៉ྷͳDDDͱγϏΞͳύϑΥʔϚϯεཁ݅ͷόϥϯεΛ ৗʹߟ͑Δ

Slide 43

Slide 43 text

τϥϯβΫγϣϯʹ͍ͭͯ • "ू໿ʢAggregateʣ͸τϥϯβΫγϣϯ੔߹ੑͷڥքͱಉٛ" ʢIDDD p.340ʣͳͷͰɺҰͭͷू໿Λѻ͍ͬͯΔؒ͸Repositoryͷ தʹด͡Δ͜ͱ͕Ͱ͖Δɻ • ໰୊͸ɺෳ਺ͷू໿ͷߋ৽Λ୯ҰͷτϥϯβΫγϣϯ಺ͰߦΘͳ͚ Ε͹͍͚ͳ͍࣌ 1. ݁Ռ੔߹ੑͰे෼Ͱ͸ͳ͍͔Λݕ౼͢Δ
 ˠτϥϯβΫγϣϯͷແ͍ੈք΁ʢႈ౳ͳૢ࡞͸ඞཁʣ 2. ৽͍͠ू໿ͱͯ͠ఆٛ͢Δ
 ˠ͜ΕΛ܁Γฦ͢ͱڊେͳू໿ʹͳͬͯ͠·͏ͷͰ஫ҙ

Slide 44

Slide 44 text

ίωΫγϣϯʹ͍ͭͯ • RepositoryΛUseCase૚ʹݶఆ͍ͯ͠ΔͷͰίωΫγϣ ϯΦϒδΣΫτ͕ݱΕΔͷ͸͜͜·ͰͰࡁΜͰ͍Δ… • ΋͠ɺυϝΠϯαʔϏεͰ΋RepositoryʹΞΫηεͨ͠ ͍৔߹͸ίωΫγϣϯΛ౉͞ͳ͚Ε͹͍͚ͳ͍͕ɺ͜Ε ͸υϝΠϯͷؔ৺Ͱ͸ͳ͍఺ʹ્·ΕΔ • implicitͰݱΕΔ෼ʹ͸ڐ༰͢Δʁ • ϨΠϠεʔύʔλΠϓʢجఈΫϥεʣʹӅṭ͢Δʁ

Slide 45

Slide 45 text

Ϣʔεέʔεۦಈ։ൃʹ ग़ձͬͨ࿩ ઃܭͷલʹ༧උઃܭΛͯ͠ ᐆດੑΛഉআ͢Δ

Slide 46

Slide 46 text

͍͟DDDΛ࣮ફ͠Α͏ͱ͢Δͱ • Կ͔Β࢝Ίͯྑ͍͔෼͔Βͳ͍ • υϝΠϯΤΩεύʔτͱͲ͏࿩ͤ͹ྑ͍͔෼͔Βͳ͍ • UIແ͠ͰυϝΠϯ͚ͩΛ࿩ͯ͠΋্ख͘఻ΘΒͳ͍ • ࠷ॳ͔ΒৄࡉͳΫϥεਤΛॻ͜͏ͱͯ͠͠·͏ • ࢼ͠ʹϞσϧ͚ͩͰ΋ॻ͍ͯΈΔͱࢥ͍ͷ֎ϘϦϡʔϛΟ • υϝΠϯϞσϧʢΫϥεਤʣ͔Β࢓༷ΛಡΈऔΔͷ͕ࠔ೉ • ૝૾ͯ͠ಡΈऔΖ͏ͱ͢Δͱᐆດ͞ʹ௚໘͢Δ ㅟ ㅟ ㅟ ※ฐࣾࣄྫ͚ͩͰͳ͘ໝ૝΋ؚ·Ε·͢

Slide 47

Slide 47 text

υϝΠϯϞσϧ͚ͩʹ ண໨͍ͯ͠Δͱ ྲྀΕ͕Θ͔Βͳ͘ͳΔ

Slide 48

Slide 48 text

IUUQCMPHUIMJHIUDPNVODMFCPC UIFDMFBOBSDIJUFDUVSFIUNM ͲͪΒ΋Ϗδωεϧʔϧ 6TF$BTF͸ ΞϓϦέʔγϣϯݻ༗ͷ Ϗδωεϧʔϧ

Slide 49

Slide 49 text

Ϣʔεέʔεʢ΍ετʔϦʔʣ ʹΑͬͯυϝΠϯϞσϧ͸ ࢖ΘΕΔ

Slide 50

Slide 50 text

ϑ Υ ϩ ʔ

Slide 51

Slide 51 text

Ϣʔεέʔε೉ຽ

Slide 52

Slide 52 text

ॻ੶ ʮϢʔεέʔεۦಈ։ൃ࣮ફΨΠυʯ • Use Case Driven Object Modeling with UML • ICONIXϓϩηεͷղઆຊ • ඇৗʹܰշͳޠΓޱʢ͏ͻΌʔͱ͔ग़ͯ͘Δʣ • एׯXP൱ఆʢߟ͑ࣗମ͸XPΑΓલ͔Β͋Δʣ • ͍͖ͳΓઃܭʹೖΔͷͰ͸ͳͯ͘ɺ·ͣ͸෼ੳΛͪΌΜͱ͠Α͏ɻ • ಛʹʮՄೳͳݶΓ؆୯ʹ(DTSTTCPW)ʯͱʮͦΜͳ΋ͷ͸ඞཁͳ͍ (YAGNI)ʯΛཧ༝ʹ୅ସίʔεʢΤϥʔέʔεʣΛߟྀʹؚΊͳ͍ ͜ͱ͸ഁ໓΁ͷಓͱ͍ͯ͠Δɻ

Slide 53

Slide 53 text

·࣮ͩફஈ֊Ͱ͸ͳ͍ͷͰ ࠓճ͸঺հ͚ͩɾɾɾ

Slide 54

Slide 54 text

ICONIXϓϩηε͕໨ࢦ͢τίϩ • ᐆດ͞Λഉআ͢Δ͜ͱ͕ୈҰ • Ͳ͔ͪΒͱ͍͏ͱυΩϡϝϯτେࣄ࿦ௐ • ͱݴͬͯ΋ɺʢίʔυϑΝʔετͰ͸ͳ͍ͩ ͚Ͱʣ໨తΛୡ੒͢Δ͜ͱʹ஫ྗͯ͠ɺମࡋ ΍༨෼ͳ΋ͷΛ࡟͗མͱͨܰ͠ྔͳυΩϡ ϝϯτΛਪ঑͍ͯ͠Δɻ

Slide 55

Slide 55 text

ICONIXϓϩηε͸DDDͷ࣮ફ ࣮͸͔͜͜Β ࢝·Δ υϝΠϯϞσϧΛҭͯΔͨΊʹɺ ϢʔεέʔεΛ࢖ͬͯۦಈ͍ͯ͠Δ ϢʔεέʔεϞσϧ͸ ίϯςΩετͷൃݟʹ ΋໾ཱͭ ಈతͳϫʔΫϑϩʔͱ ੩తͳϫʔΫϑϩʔ͕ ͋Δ ϩόετωε෼ੳ౳Λ͠ͳ͕Β υϝΠϯϞσϧΛߋ৽

Slide 56

Slide 56 text

DDDͰ͍͏࣮ફతϞσϥ ΛϓϩηεԽͨ͠΋ͷ͕ICONIX ʢͱߟ͑Δͱ෼͔Γ΍͍͢ʣ

Slide 57

Slide 57 text

–ʮϢʔεέʔεۦಈ։ൃ࣮ફΨΠυʯ1ষத “௨ৗɺԿΒ͔ͷઃܭ࡞ۀΛߦΘͳ͍ݶ Γɺࣗ෼͕औΓѻ͏ཁٻΛਖ਼͘͠ཧղ͢ Δ͜ͱ͸Ͱ͖ͳ͍ɻ”

Slide 58

Slide 58 text

શͯͷϢʔεέʔεΛ෼ੳ͠ͳ ͚Ε͹͍͚ͳ͍ʁ • ͍͖ͳΓશͯͷϢʔεέʔεΛ෼ੳ͢Δඞཁ͸ ͳ͍ɻICONIXϓϩηε͸1ͭͷϢʔεέʔε ͕͋Ε͹ۦಈͤ͞Δ͜ͱ͕Ͱ͖Δɻͱ͸͍ ͑ɺͨͬͨ̍ͭͷখ͞ͳϢʔεέʔεͰࡁΉι ϑτ΢ΣΞͷํ͕ك • Ͳ͏΍ͬͯείʔϓΛߜ͍͔ͬͯ͘ʹͭ ͍ͯ͸ɺϢʔβʔετʔϦʔϚοϐϯά ͕ࢀߟʹͳΓ·͢ɻ

Slide 59

Slide 59 text

Clean Architectureͱͷ਌࿨ੑ • "UseCase૚"ͱͦͷ·Μ·ͷ૚͕͋ΔͷͰؔ܎͕෼͔Γ΍͍͢ʢ"ΞϓϦέʔ γϣϯαʔϏε"ͱ͍͏ݴ༿ΑΓ͸ྑ͍ͱࢥ͏ɻϢʔεέʔεͱ͍͏ݴ༿Ͱͳ͍ ͷ͸ɺʢICONIXͳͲΛ࢖Θͳ͍ͱʣৄࡉͳٕज़ཁૉΛೖΕͯ͠·͍΍͍͔͢Β Ͱ͸ʁʣ • ۩ମతͳϑϨʔϜϫʔΫ΍DB͕ܾ·͍ͬͯͳͯ͘΋։ൃΛਐΊΔ͜ͱ͕Ͱ͖Δ • ICONIXϓϩηε͸UseCase૚ͱDomain૚ͷؔ৺ࣄʹ͍ͭͯѻ͏ • Clean Architecture͸ΞϓϦέʔγϣϯʢUseCase&DomainʣͱΠϯϑϥΛ ෼཭͢Δ • Hexagonal΍OnionͰ΋ಉ༷

Slide 60

Slide 60 text

ద༻΁ͷߟ࡯̍ ਖ਼ࣜͳυΩϡϝϯτʹ͠ͳ͍ • ސ٬ͱʮԿΛͭ͘Δͷ͔ʯΛᐆດ͞Λղফͯ͠߹ҙ͢Δ͜ͱ͕େࣄ • ICONIXϓϩηεͰ͸ʮ࡞੒͢ΔυΩϡϝϯτ͸͜ΕͰɺͦΕΛϨ Ϗϡʔ͢Δػձ͸͍ͭʯΛ໌֬ʹఆ͍ٛͯ͠Δɻ • ਖ਼֬ʹॻ͘͜ͱ͸ਪ঑͍ͯ͠ͳ͍ʢॏްͳυΩϡϝϯτ͸଍ ᐫʣɻUML࢓༷ʹ४ڌ͢Δඞཁ͸ͳ͍ɻۃ୺ͳ࿩ɺϗϫΠτ Ϙʔυͷམॻ͖Ͱ΋ྑ͍ʢͱࢥ͏ʣɻ • ॻ੶தͰ͸πʔϧΛ࢖͏͜ͱΛલఏʹɺίʔυͱઃܭΛಉظ͢ Δ͜ͱ͸ڧ͘ਪ঑͞Ε͍ͯΔɻࢴͱԖච͕Ұ൪ڧ͍͔΋͠Εͳ ͍ɻʮΊ΋Ͱ͘͢ʯͱ͔ࢼͯ͠Έ͍ͨɻ

Slide 61

Slide 61 text

ద༻΁ͷߟ࡯̎ ੔߹ੑཁٻͷݕ౼ • ސ٬͕ࢀՃ͢ΔϨϏϡʔ͸༧උઃܭϨϏϡʔ·ͰʢγʔέϯεਤҎ ߱͸ٕज़త͗͢ΔʣɻؾΛ͚ͭͳ͍ͱϩόετωε෼ੳͷஈ֊Ͱ ͸੔߹ੑཁٻͷදݱ·Ͱٴ͹ͳ͍ؾ͕͢Δɻ • શͯʹτϥϯβΫγϣϯ͕ඞཁͱ͸ݶΒͣɺ݁Ռ੔߹ੑͰे෼ ͳέʔε΋ଟ͍͸ͣɻ • ༧උઃܭϨϏϡʔͷஈ֊·Ͱʹ੔߹ੑͷཁٻʢϨϕϧʣʹ͍ͭ ͯݕ౼ͨ͠ํ͕ྑ͍ͱࢥ͏ɻ • "τϥϯβΫγϣϯͷ෼ੳΛ͔ͯ͠ΒͰͳ͍ͱɺू໿ͷઃܭͷྑ ͠ѱ͠Λਖ਼͘͠൑அ͢Δ͜ͱ͸Ͱ͖ͳ͍"ʢIDDD p.340-344ʣ

Slide 62

Slide 62 text

։ൃϓϩηεͷ มߋ͸೉͍͠ɾɾɾ νʔϜͷܾ·Γʁ ձࣾͰنఆ͞Ε͍ͯΔʁ ސ٬͔Βࢦఆ͞Ε͍ͯΔʁ

Slide 63

Slide 63 text

–Team Geek ʮ5.6 ر๬͸࢒͞Ε͍ͯΔʯΑΓ “࠷ॳʹ΍Βͳ͚Ε͹͍͚ͳ͍ͷ͸ɺ࢓ࣄ Λୡ੒͢ΔͨΊʹԿ͔Λม͑Δ͜ͱͩɻ”

Slide 64

Slide 64 text

ͦΕͰ΋ਏ͘ͳͬͨΒɾɾɾ

Slide 65

Slide 65 text

XXXXBOUFEMZDPNQSPKFDUT ΠϠʔ΢ϚΫπφΨολφʔ

Slide 66

Slide 66 text

·ͱΊ • DDD
 + Clean Architecture
 + Use Case Driven Object Modeling(ICONIX)
 ͷηοτ͸૬ੑ͕ྑͦ͞͏ • ICONIX͸ܰྔͱ͸͍͑ɺͦͷதͰ΋Ͳ͜·ͰΛ࣮ࢪ͢Δ͔ ސ٬΍νʔϜͱςʔϥϦϯάͨ͠ํ͕ྑ͍͔΋ • ֖Λ։͚Ε͹஌͍ͬͯΔਓʹ͸౰ͨΓલ…
 ૣ͘஌Γ͔ͨͬͨ
 ʢଞͷ࣮ફख๏΋͝ଘ஌ͷํ͕͍Βͬ͠ΌΕ͹ޙͰڭ͍͑ͯͩ͘͞ʣ

Slide 67

Slide 67 text

Q & A

Slide 68

Slide 68 text

ࢀߟɿDDDฤ • ॻ੶ʮΤϦοΫɾΤϰΝϯεͷυϝΠϯۦಈઃܭʯʢᠳӭࣾʣ • ॻ੶ʮ࣮ફυϝΠϯۦಈઃܭʯʢᠳӭࣾʣ • ਿຊ ܒ ࢯʮυϝΠϯۦಈઃܭ at DDD.rb #5ʯ • ਿຊ ܒ ࢯʮ2ͭͷυϝΠϯϞσϧʕDDDͷؚҙʯ • ૿ా ږ ࢯʮ3ि࿈ଓDDDͦͷ1 υϝΠϯۦಈઃܭͷجຊΛཧղ͢Δʯ • ૿ా ږ ࢯʮ3ि࿈ଓDDDͦͷ2 ਂ͍Ϟσϧͷ୳ٻ(υϝΠϯۦಈઃܭ ୈ̏෦) ʯ • ૿ా ږ ࢯʮ3ि࿈ଓDDDͦͷ3 υϝΠϯۦಈઃܭ ઓུతઃܭ ʯ • InfoQʮυϝΠϯۦಈઃܭɾ։ൃͷ࣮ફʯ • InfoQʮίϯςΩετϚοϐϯάʹΑΔઓུతυϝΠϯۦಈઃܭʯ • InfoQʮShane HastieࢯɺϏδωε՝୊ʹର͢ΔΞδϟΠϧϚΠϯυηοτͷద༻ʹ͍ͭͯޠΔʯ

Slide 69

Slide 69 text

ࢀߟɿClean Architectureฤ • ετϥςδοΫνϣΠεʮϨΠϠʔυΞʔΩςΫνϟʯ • Alistair Cockburn ࢯʮHexagonal Architectureʯʢ຋༁ɿ෢౻ ࢯʣ • Jeffrey Palermo ࢯʮThe Onion Architectureʯ • Robert Martin ࢯʮThe Clean Architectureʯʢ຋༁ɿ෢౻ ࢯʣ • Thomas PIERRAIN ࢯʮA zoom on the hexagonal/clean/onion architectureʯ • InfoQʮυϝΠϯۦಈઃܭͱΦχΦϯΞʔΩςΫνϟʯ • InfoQʮΞʔΩςΫνϟͷ໨త͸ҙਤͰ͋ΓɺϑϨʔϜϫʔΫͰ͸ͳ͍ʯ • James Coglan ࢯʮ໋ྩܕͷίʔϧόοΫɺؔ਺ܕͷϓϩϛε: Node ͕ҳͨ͠࠷େͷػձʯ(຋༁ɿԬຊ ࢯ) • Togetter·ͱΊʮ”໋ྩܕͷίʔϧόοΫɺؔ਺ܕͷϓϩϛε”΁ͷ൓Ԡʢͱͦͷޙʣʯ • _kondeiࢯʮ࣋ଓՄೳͳ։ൃΛ໨ࢦ͢ ~ υϝΠϯɾϢʔεέʔεۦಈʢΫϦʔϯΞʔΩςΫνϟʣ + ୯ํ޲ʹ੍ݶͨ͠ॲཧ + FRPʯ • ૿ా ږ ࢯʮυϝΠϯϞσϧத৺ͷΞʔΩςΫνϟʯ

Slide 70

Slide 70 text

ࢀߟɿϢʔεέʔεۦಈ։ൃฤ • ॻ੶ʮϢʔεέʔεۦಈ։ൃ࣮ફΨΠυʯʢᠳӭࣾʣ • ॻ੶ʮΤΫετϦʔϜϓϩάϥϛϯάୈ2൛৽༁ʯʢΦʔϜࣾʣ • ॻ੶ʮϢʔβʔετʔϦʔϚοϐϯάʯʢΦϥΠϦʔδϟύϯʣ • ૿ా ږ ࢯʮ࣮ફ ICONIXϓϩηεɿγʔέϯεਤͱΫϥεਤʯ • ૿ా ږ ࢯʮ࣮ફ ICONIXϓϩηεɿυϝΠϯۦಈʯ • WikipediaʮICONIXϓϩηεʯ • EZʮϏδωεཁٻͷٸܹͳมԽʹରԠ͢Δ։ൃϓϩηεͱ͸ʁʯ