Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
コードをどまんなかに据えたモデリング-Scala版 / Modeling with code ...
Search
yoshiyoshifujii
April 14, 2020
Technology
0
140
コードをどまんなかに据えたモデリング-Scala版 / Modeling with code in the middle-Scala version
【オンライン開催】04/14(火) Scala関西勉強会 - 2020年04月版
https://connpass.com/event/163551/
yoshiyoshifujii
April 14, 2020
Tweet
Share
More Decks by yoshiyoshifujii
See All by yoshiyoshifujii
技術的負債と戦略的に戦わざるを得ない場合のオブザーバビリティ活用術 / Leveraging Observability When Strategically Dealing with Technical Debt
yoshiyoshifujii
0
200
プロダクトオーナーの視座から見た信頼性とオブザーバビリティ / Reliability and Observability from the Perspective of a Product Owner
yoshiyoshifujii
2
1.6k
プロダクトオーナーがFour Keys + 信頼性に思うところ / Product Owners Think of Four Keys + Reliability
yoshiyoshifujii
0
560
Recapping Chatwork Scala Journey - ScalaMatsuri2023
yoshiyoshifujii
0
2.8k
ここ数ヶ月でAkkaを勉強した方法について紹介 / I have studied Akka in the past few months
yoshiyoshifujii
1
290
Chatworkのドメインをモデリングした / Modeling Chatwork domain
yoshiyoshifujii
0
890
サマーインターンシップ2019で学生とDDDなScala開発に取り組んだ / Working on DDD and Scala development with students at Summer Internship 2019
yoshiyoshifujii
2
4.2k
Clean Architecture in Practice @ScalaMatsuri2019
yoshiyoshifujii
9
4.1k
実践 Clean Architecture
yoshiyoshifujii
13
10k
Other Decks in Technology
See All in Technology
【5分でわかる】セーフィー エンジニア向け会社紹介
safie_recruit
0
27k
Zero Data Loss Autonomous Recovery Service サービス概要
oracle4engineer
PRO
2
7.8k
SaaS型なのに自由度の高い本格CMSでサイト構築と運用のコスパ&タイパUP! MovableType.net の便利機能とユーザー事例のご紹介
masakah
0
110
データグループにおけるフロントエンド開発
lycorptech_jp
PRO
1
100
Lazy application authentication with Tailscale
bluehatbrit
0
210
Sansanのデータプロダクトマネジメントのアプローチ
sansantech
PRO
0
160
Backlog ユーザー棚卸しRTA、多分これが一番早いと思います
__allllllllez__
1
150
Should Our Project Join the CNCF? (Japanese Recap)
whywaita
PRO
0
340
SEQUENCE object comparison - db tech showcase 2025 LT2
nori_shinoda
0
140
MobileActOsaka_250704.pdf
akaitadaaki
0
130
いつの間にか入れ替わってる!?新しいAWS Security Hubとは?
cmusudakeisuke
0
130
KubeCon + CloudNativeCon Japan 2025 Recap
ren510dev
1
380
Featured
See All Featured
Measuring & Analyzing Core Web Vitals
bluesmoon
7
510
GitHub's CSS Performance
jonrohan
1031
460k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
10
950
Building Flexible Design Systems
yeseniaperezcruz
328
39k
A designer walks into a library…
pauljervisheath
207
24k
[RailsConf 2023] Rails as a piece of cake
palkan
55
5.7k
Building a Scalable Design System with Sketch
lauravandoore
462
33k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
357
30k
Reflections from 52 weeks, 52 projects
jeffersonlam
351
20k
The Straight Up "How To Draw Better" Workshop
denniskardys
234
140k
Building Applications with DynamoDB
mza
95
6.5k
Done Done
chrislema
184
16k
Transcript
Scala関西 Chatwork株式会社 FUJII Yoshitaka コードをどまんなかに据えた モデリング - Scala版
自己紹介 - FUJII Yoshitaka - @yoshiyoshifujii - Chatwork株式会社 - Scala関西
- 登壇 - ScalaMatsuri2019 - 実践 Clean Architecture - 趣味 - ⛰ ⛺ ♂ 庭DIY
アジェンダ 1. 課題感 2. JIG 3. sbt-jig 4. sbt-jig-tutorial 5.
コードへのフィードバック例 3
01 課題感
課題感 - モデリングどうやりますか - ホワイトボードに書く - ツールを使う - astah -
PlantUML - Miro 5
課題感 - 図に書いた通りに実装できていますか - 認識はズレていませんか - コードとドキュメントは同期されていま すか - どうやって担保しますか
6
課題感 - 図とコードとテストの変更のリズムは どうですか - さくさく変更できますか - 図からコード、コードをテスト、 コードを変更ってぐるぐるしてると、 図は…あとで良いや
ってなりがち 7
02 JIG
コードをどまんなかに - コードに軸足を置く - 最初はホワイトボードとかで認識合わせ る(Miroはいいぞ ) - 意図を込めてコードを書き、意図が表現 されたドキュメントを見る
9
コードをどまんなかに 10 https://speakerdeck.com/irof/kodowodomannakaniju-etashe-ji-apuroti
コードをどまんなかに - JIG Java Instant-document Gazer (ドキュメントは一時的に見るもの) - https://github.com/dddjava/jig -
JIGは、バイトコードおよびソースコードから、 一覧(Excel形式)やダイアグラム(SVG形式)を 出力するツールです 11
JIG 三層+ドメインモデル のアーキテクチャで実 装されたコードから分 析・設計情報を出力す るツール 12
JIGのDiagramたち 13 https://jigzag.work/
03 sbt-jig
Scalaに対応した - JIGにScalaのソースコードを解析できるように拡張部 分を追加させていただいた - https://github.com/dddjava/jig/pull/424 - https://irof-web.s3.amazonaws.com/jig/master/use-case- and-fellows.svg 15
sbt-jigを作った - https://github.com/yoshiyoshifujii/sbt-jig - Scalaのソースから、Scaladocを読み取り、別名を扱え るようにした - JIGに追加した org.dddjava.jig.domain.model.jigloaded.alias.ScalaSourceAliasReader をsbt-jig側で実装
- Scalametaを使って解析 16
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" )
sbt-jig - Scalaのバージョンを見たうえで、classesが出力される ディレクトリを導出 18 def makeClasses(): Initialize[String] = Def.setting
{ s"target/scala-${scalaBinaryVersion.value}/classes" }
04 sbt-jig-tutorial
sbt-jig-tutorialを作った - https://github.com/yoshiyoshifujii/sbt-jig-tutorial - jig-tutorialがあったので、sbt-jig用を作った - ぜひお試しください 20
05 コードへの フィードバック例
Roleオブジェクト - DCIアーキテクチャ - https://digitalsoul.hatenadiary.org/entry/20100131/1264925022 - オブジェクト指向の本質が人間のメンタルモデルを捉え ることにあるとした上で、問題と解決方法を提示 - 問題は、構造を捉えることに長けている反面、ふるまい
を捉えることが苦手 - 特定のふるまいをどのクラスにおくべきか - エンティティクラスが大量のメソッドで肥大化する - 今回は、 Factory Method について捉えた 22
Roleオブジェクト 23 - グループチャットにメッセージを生成する Factory Methodを実装する - グループチャットは、メッセージを生成す るうえで、集約由来の生成ロジックを保持 しており、そのロジックを通してしか、
メッセージの生成を許可しない - グループチャットのふるまいとして持たせ ることは、良さそうに思える
Roleオブジェクト 24 - グループチャットを通して生成 する別の集約のエンティティと して、ファイルやタスク、ライ ブ… - グループチャットが持つ Factoryとしてのメソッドが増
え、肥大化する
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 }
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) } }
働くをもっと楽しく、創造的に