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
120
コードをどまんなかに据えたモデリング-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
プロダクトオーナーの視座から見た信頼性とオブザーバビリティ / Reliability and Observability from the Perspective of a Product Owner
yoshiyoshifujii
1
1.4k
プロダクトオーナーがFour Keys + 信頼性に思うところ / Product Owners Think of Four Keys + Reliability
yoshiyoshifujii
0
460
Recapping Chatwork Scala Journey - ScalaMatsuri2023
yoshiyoshifujii
0
2.6k
ここ数ヶ月でAkkaを勉強した方法について紹介 / I have studied Akka in the past few months
yoshiyoshifujii
1
250
Chatworkのドメインをモデリングした / Modeling Chatwork domain
yoshiyoshifujii
0
800
サマーインターンシップ2019で学生とDDDなScala開発に取り組んだ / Working on DDD and Scala development with students at Summer Internship 2019
yoshiyoshifujii
2
4k
Clean Architecture in Practice @ScalaMatsuri2019
yoshiyoshifujii
9
3.9k
実践 Clean Architecture
yoshiyoshifujii
13
10k
k8sもよく分かってないけどRancherを兎に角さわってみた
yoshiyoshifujii
1
570
Other Decks in Technology
See All in Technology
Evangelismo técnico: ¿qué, cómo y por qué?
trishagee
0
360
DMARC 対応の話 - MIXI CTO オフィスアワー #04
bbqallstars
1
160
第1回 国土交通省 データコンペ参加者向け勉強会③- Snowflake x estie編 -
estie
0
130
100 名超が参加した日経グループ横断の競技型 AWS 学習イベント「Nikkei Group AWS GameDay」の紹介/mediajaws202411
nikkei_engineer_recruiting
1
170
【Pycon mini 東海 2024】Google Colaboratoryで試すVLM
kazuhitotakahashi
2
500
BLADE: An Attempt to Automate Penetration Testing Using Autonomous AI Agents
bbrbbq
0
300
複雑なState管理からの脱却
sansantech
PRO
1
140
テストコード品質を高めるためにMutation Testingライブラリ・Strykerを実戦導入してみた話
ysknsid25
7
2.6k
データプロダクトの定義からはじめる、データコントラクト駆動なデータ基盤
chanyou0311
2
300
The Role of Developer Relations in AI Product Success.
giftojabu1
0
120
スクラム成熟度セルフチェックツールを作って得た学びとその活用法
coincheck_recruit
1
140
20241120_JAWS_東京_ランチタイムLT#17_AWS認定全冠の先へ
tsumita
2
250
Featured
See All Featured
[RailsConf 2023] Rails as a piece of cake
palkan
52
4.9k
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
126
18k
StorybookのUI Testing Handbookを読んだ
zakiyama
27
5.3k
Automating Front-end Workflow
addyosmani
1366
200k
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
29
2.3k
Building Adaptive Systems
keathley
38
2.3k
The Language of Interfaces
destraynor
154
24k
Designing Experiences People Love
moore
138
23k
Optimizing for Happiness
mojombo
376
70k
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Exploring the Power of Turbo Streams & Action Cable | RailsConf2023
kevinliebholz
27
4.3k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
356
29k
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) } }
働くをもっと楽しく、創造的に