Upgrade to Pro — share decks privately, control downloads, hide ads and more …

DDD + Clean Architecture + UCDOM Essence版

DDD + Clean Architecture + UCDOM Essence版

http://ddd-cqrs-es.connpass.com/event/27181/
「Reactive Messaging Patternsプレ読書会 - CQRS、ESの基本を学ぶ -」の資料です。
Embeddedなままだと各種リンクが有効ではないので、気になる方は"Download PDF"よりご参照ください。

Full版はコチラ:https://speakerdeck.com/yoskhdia/ddd-plus-clean-architecture-plus-ucdom-fullban

Yoshitaka Okuda

March 16, 2016
Tweet

More Decks by Yoshitaka Okuda

Other Decks in Programming

Transcript

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

    View Slide

  2. 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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    InfoQʮίϯςΩετϚοϐϯάʹΑΔઓུతυϝΠϯۦಈઃܭʯΛࢀর

    View Slide

  9. υϝΠϯͱίϯςΩετͷؔ܎
    υϝΠϯ
    ίϯςΩετ
    αϒυϝΠϯ
    ίΞυϝΠϯ
    • ఺ઢɿ

    υϝΠϯڥք
    • ੺࣮ઢɿ

    ίϯςΩετڥք
    • ίϯςΩετ͸͍
    ͔ͭ͘ͷυϝΠϯ
    ڥքʹލΔ͜ͱ͕
    ͋Δ
    • ཧ૝͸αϒυϝΠ
    ϯͱίϯςΩετ
    ͕1ର1 αϒυϝΠϯ

    View Slide

  10. ଓ͖͸ࢀߟࢿྉͰ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  17. Clean Architecture
    ΋ͦͷҰ೿

    View Slide

  18. CMPHUIMJHIUDPNVODMFCPCUIF
    DMFBOBSDIJUFDUVSFIUNM

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  22. ઃܭͷϙΠϯτɿڥքͷԣஅ
    • ԁͷํʹ໨͕ߦ͖͕͚ͪͩΕͲɺઃܭͷ͏
    ͑Ͱ͸͕ͬͪ͜ॏཁ
    • ௨ৗɺController͔Βೖ͖ͬͯͯPresenter
    ʹग़ͯߦ͘ྲྀΕ
    • UseCase͸֎૚Λ஌Βͳ͍ͷͰɺग़ྗΛฦ
    ͢ʹ͸ґଘؔ܎ٯసͷݪଇΛ࢖͍ͬͯΔ

    ʢDependency Inversion Principleʣ
    • ૚ͷڥքΛอͪͳ͕ΒॲཧϑϩʔΛ࣮ݱ
    ৄࡉ͸ޙ΄Ͳ

    View Slide

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

    View Slide

  24. ࣮૷αϯϓϧ

    github.com/yoskhdia/
    cleanArchSample

    View Slide

  25. ύοέʔδߏ੒
    • Domain(Entities)૚
    • Contract૚
    • Domain૚ͱͷڮ౉͠

    ʢDIΛ࢖͏ͷͰΠϯλϑΣʔε͸ผʹ͍ͯ͠Δʣ
    • UseCase૚
    • Adapter૚
    • Repositoryͷ࣮૷Ϋϥε΋͜͜
    • ʢExternal૚ʣ
    • ϑϨʔϜϫʔΫ΍ϥΠϒϥϦͷ૚ͱ͍͏Ґஔ͚ͮ
    ̐૚Ͱͳͯ͘΋0,

    View Slide

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

    View Slide

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

    View Slide

  28. 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ʹҕৡ

    View Slide

  29. 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Λฦ͢

    View Slide

  30. Output Port
    trait Callback[Result] {


    def onSuccess(result: Result): Unit


    def onFailure(t: Throwable): Unit

    }
    ΞϓϦέʔγϣϯϩδοΫͷΤϥʔ΋
    ಛผͳ&YDFQUJPOΛ༻ҙͯ͠ฦ͢Α͏ʹ͍ͯ͠Δ
    ʢ+BWBͷ׳शʹ͍ۙʣ
    ※Callback vs Promise(Future)͸Full൛Ͱิ଍

    View Slide

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

    View Slide

  32. Use Caseͷఆٛ
    package contract.usecase


    import contract.{PushPort, UseCase}

    import domain.{GroupId, UserId}


    trait PickLeaderUseCase extends UseCase with PushPort[GroupId, UserId]
    ࣮͸αϘ͍ͬͯΔ
    6TF$BTF૚Ͱѻ͍΍͍͢
    ΦϒδΣΫτ %50
    ʹ͢Δ

    View Slide

  33. 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 // ୭ΛͲ͏Ϧʔμʹ͢Δ͔͸υϝΠϯ஌ࣝ

    }

    }

    }
    ΠϯλϑΣʔεΛ࢖͏
    %*ͰґଘΛ୯ํ޲ʹ

    View Slide

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

    View Slide

  35. 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൛Ͱิ଍
    ೖྗσʔλ͔Βͷม׵͕੹຿

    View Slide

  36. 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))

    }

    }

    } ग़ྗσʔλ΁ͷม׵͕੹຿

    View Slide

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

    View Slide

  38. ϓϩμΫτͰͷऔΓ૊Έ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  43. τϥϯβΫγϣϯʹ͍ͭͯ
    • "ू໿ʢAggregateʣ͸τϥϯβΫγϣϯ੔߹ੑͷڥքͱಉٛ"
    ʢIDDD p.340ʣͳͷͰɺҰͭͷू໿Λѻ͍ͬͯΔؒ͸Repositoryͷ
    தʹด͡Δ͜ͱ͕Ͱ͖Δɻ
    • ໰୊͸ɺෳ਺ͷू໿ͷߋ৽Λ୯ҰͷτϥϯβΫγϣϯ಺ͰߦΘͳ͚
    Ε͹͍͚ͳ͍࣌
    1. ݁Ռ੔߹ੑͰे෼Ͱ͸ͳ͍͔Λݕ౼͢Δ

    ˠτϥϯβΫγϣϯͷແ͍ੈք΁ʢႈ౳ͳૢ࡞͸ඞཁʣ
    2. ৽͍͠ू໿ͱͯ͠ఆٛ͢Δ

    ˠ͜ΕΛ܁Γฦ͢ͱڊେͳू໿ʹͳͬͯ͠·͏ͷͰ஫ҙ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  50. ϑ
    Υ
    ϩ
    ʔ

    View Slide

  51. Ϣʔεέʔε೉ຽ

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  66. ·ͱΊ
    • DDD

    + Clean Architecture

    + Use Case Driven Object Modeling(ICONIX)

    ͷηοτ͸૬ੑ͕ྑͦ͞͏
    • ICONIX͸ܰྔͱ͸͍͑ɺͦͷதͰ΋Ͳ͜·ͰΛ࣮ࢪ͢Δ͔
    ސ٬΍νʔϜͱςʔϥϦϯάͨ͠ํ͕ྑ͍͔΋
    • ֖Λ։͚Ε͹஌͍ͬͯΔਓʹ͸౰ͨΓલ…

    ૣ͘஌Γ͔ͨͬͨ

    ʢଞͷ࣮ફख๏΋͝ଘ஌ͷํ͕͍Βͬ͠ΌΕ͹ޙͰڭ͍͑ͯͩ͘͞ʣ

    View Slide

  67. Q & A

    View Slide

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

    View Slide

  69. ࢀߟɿ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ʯ
    • ૿ా ږ ࢯʮυϝΠϯϞσϧத৺ͷΞʔΩςΫνϟʯ

    View Slide

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

    View Slide