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

コードをどまんなかに据えたモデリング-Scala版 / Modeling with code in the middle-Scala version

コードをどまんなかに据えたモデリング-Scala版 / Modeling with code in the middle-Scala version

【オンライン開催】04/14(火) Scala関西勉強会 - 2020年04月版
https://connpass.com/event/163551/

yoshiyoshifujii

April 14, 2020
Tweet

More Decks by yoshiyoshifujii

Other Decks in Technology

Transcript

  1. Scala関西
    Chatwork株式会社
    FUJII Yoshitaka
    コードをどまんなかに据えた
    モデリング - Scala版

    View Slide

  2. 自己紹介
    - FUJII Yoshitaka
    - @yoshiyoshifujii
    - Chatwork株式会社
    - Scala関西
    - 登壇
    - ScalaMatsuri2019
    - 実践 Clean Architecture
    - 趣味
    - ⛰ ⛺ ‍♂ 庭DIY

    View Slide

  3. アジェンダ
    1. 課題感
    2. JIG
    3. sbt-jig
    4. sbt-jig-tutorial
    5. コードへのフィードバック例
    3

    View Slide

  4. 01
    課題感

    View Slide

  5. 課題感
    - モデリングどうやりますか
    - ホワイトボードに書く
    - ツールを使う
    - astah
    - PlantUML
    - Miro
    5

    View Slide

  6. 課題感
    - 図に書いた通りに実装できていますか
    - 認識はズレていませんか
    - コードとドキュメントは同期されていま
    すか
    - どうやって担保しますか
    6

    View Slide

  7. 課題感
    - 図とコードとテストの変更のリズムは
    どうですか
    - さくさく変更できますか
    - 図からコード、コードをテスト、
    コードを変更ってぐるぐるしてると、
    図は…あとで良いや ってなりがち
    7

    View Slide

  8. 02
    JIG

    View Slide

  9. コードをどまんなかに
    - コードに軸足を置く
    - 最初はホワイトボードとかで認識合わせ
    る(Miroはいいぞ  )
    - 意図を込めてコードを書き、意図が表現
    されたドキュメントを見る
    9

    View Slide

  10. コードをどまんなかに
    10
    https://speakerdeck.com/irof/kodowodomannakaniju-etashe-ji-apuroti

    View Slide

  11. コードをどまんなかに
    - JIG
    Java Instant-document Gazer
    (ドキュメントは一時的に見るもの)
    - https://github.com/dddjava/jig
    - JIGは、バイトコードおよびソースコードから、
    一覧(Excel形式)やダイアグラム(SVG形式)を
    出力するツールです
    11

    View Slide

  12. JIG
    三層+ドメインモデル
    のアーキテクチャで実
    装されたコードから分
    析・設計情報を出力す
    るツール
    12

    View Slide

  13. JIGのDiagramたち
    13
    https://jigzag.work/

    View Slide

  14. 03
    sbt-jig

    View Slide

  15. Scalaに対応した
    - JIGにScalaのソースコードを解析できるように拡張部
    分を追加させていただいた
    - https://github.com/dddjava/jig/pull/424
    - https://irof-web.s3.amazonaws.com/jig/master/use-case-
    and-fellows.svg
    15

    View Slide

  16. sbt-jigを作った
    - https://github.com/yoshiyoshifujii/sbt-jig
    - Scalaのソースから、Scaladocを読み取り、別名を扱え
    るようにした
    - JIGに追加した
    org.dddjava.jig.domain.model.jigloaded.alias.ScalaSourceAliasReader
    をsbt-jig側で実装
    - Scalametaを使って解析
    16

    View Slide

  17. sbt-jig
    - JIGのプロパティをsbtにも用意
    17
    override lazy val projectSettings = Seq(
    jigReports := Jig.jigReportsTask(jig).value,
    jigDocumentTypeText in jig := "",
    jigOutputDirectoryText in jig := "./target/jig",
    jigOutputOmitPrefix in jig := ".+\\.(service|domain\\.(model|type))\\.",
    jigModelPattern in jig := ".+\\.domain\\.(model|type)\\..+",
    jigProjectPath in jig := "./",
    jigDirectoryClasses in jig := Jig.makeClasses().value,
    jigDirectoryResources in jig := Jig.makeClasses().value,
    jigDirectorySources in jig := "src/main/scala"
    )

    View Slide

  18. sbt-jig
    - Scalaのバージョンを見たうえで、classesが出力される
    ディレクトリを導出
    18
    def makeClasses(): Initialize[String] =
    Def.setting {
    s"target/scala-${scalaBinaryVersion.value}/classes"
    }

    View Slide

  19. 04
    sbt-jig-tutorial

    View Slide

  20. sbt-jig-tutorialを作った
    - https://github.com/yoshiyoshifujii/sbt-jig-tutorial
    - jig-tutorialがあったので、sbt-jig用を作った
    - ぜひお試しください
    20

    View Slide

  21. 05
    コードへの
    フィードバック例

    View Slide

  22. Roleオブジェクト
    - DCIアーキテクチャ
    - https://digitalsoul.hatenadiary.org/entry/20100131/1264925022
    - オブジェクト指向の本質が人間のメンタルモデルを捉え
    ることにあるとした上で、問題と解決方法を提示
    - 問題は、構造を捉えることに長けている反面、ふるまい
    を捉えることが苦手
    - 特定のふるまいをどのクラスにおくべきか
    - エンティティクラスが大量のメソッドで肥大化する
    - 今回は、 Factory Method について捉えた
    22

    View Slide

  23. Roleオブジェクト
    23
    - グループチャットにメッセージを生成する
    Factory Methodを実装する
    - グループチャットは、メッセージを生成す
    るうえで、集約由来の生成ロジックを保持
    しており、そのロジックを通してしか、
    メッセージの生成を許可しない
    - グループチャットのふるまいとして持たせ
    ることは、良さそうに思える

    View Slide

  24. Roleオブジェクト
    24
    - グループチャットを通して生成
    する別の集約のエンティティと
    して、ファイルやタスク、ライ
    ブ…
    - グループチャットが持つ
    Factoryとしてのメソッドが増
    え、肥大化する

    View Slide

  25. Roleオブジェクト
    25
    - Factory Methodは、JIGでレポートすると相互の
    関連で出力される
    package groupChat
    import message.Message
    trait GroupChat {
    def createMessage(accountId: AccountId, body: String): Message = ???
    }
    package message
    import groupChat.RoomId
    trait Message {
    val roomId: RoomId
    }

    View Slide

  26. Roleオブジェクト
    26
    - メッセージパッケージにRoleオブジェクトを作る
    - Scalaの場合、型クラスとして作成すると扱いやすい
    package message
    import groupChat.GroupChat
    trait MessageRole[A] {
    def createMessage(self: A)(accountId: AccountId, body: String): Message
    }
    object MessageRole {
    implicit val groupChatMessageRole = new MessageRole[GroupChat] {
    override def createMessage(self: GroupChat)(accountId: AccountId, body: String): Message = ???
    }
    implicit def toMessageRoleOps[A: MessageRole](self: A) = new {
    def createMessage(accountId: AccountId, body: String): Message =
    implicitly[MessageRole[A]].createMessage(self)(accountId, body)
    }
    }

    View Slide

  27. 働くをもっと楽しく、創造的に

    View Slide