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によるDDDライクなプロダクト開発
Search
Yoshinobu Wakamatsu
May 23, 2016
Technology
0
490
ScalaによるDDDライクなプロダクト開発
2016/5/23 モバイルファクトリーさんとの勉強会で話したスライド
Yoshinobu Wakamatsu
May 23, 2016
Tweet
Share
More Decks by Yoshinobu Wakamatsu
See All by Yoshinobu Wakamatsu
金融領域におけるサービス開発の進め方
yshnb
0
670
資産運用スタートアップの開発で採用した、PlayによるClean Arcitectureでの設計・開発事例
yshnb
5
950
ReactベースのSPA開発で開発者が気をつけたいSEOのお話
yshnb
2
1.7k
Fundsのアーキテクチャについて
yshnb
0
230
Applivの開発体制から考える、理想の開発体制とは?
yshnb
2
10k
Other Decks in Technology
See All in Technology
Amazon CloudWatch を使って NW 監視を行うには
o11yfes2023
0
130
Classmethod AI Talks(CATs) #20 司会進行スライド(2025.04.10) / classmethod-ai-talks-aka-cats_moderator-slides_vol20_2025-04-10
shinyaa31
0
150
AIで進化するソフトウェアテスト:mablの最新生成AI機能でQAを加速!
mfunaki
0
130
彩の国で始めよう。おっさんエンジニアから共有したい、当たり前のことを当たり前にする技術
otsuki
0
130
Ops-JAWS_Organizations小ネタ3選.pdf
chunkof
2
130
20250411_HCCJP_AdaptiveCloudUpdates.pdf
sdosamut
1
110
Webアプリを Lambdaで動かすまでに考えること / How to implement monolithic Lambda Web Application
_kensh
7
1.3k
プロダクト開発におけるAI時代の開発生産性
shnjtk
2
220
大AI時代で輝くために今こそドメインにディープダイブしよう / Deep Dive into Domain in AI-Agent-Era
yuitosato
1
320
LangChainとLangGiraphによるRAG・AIエージェント実践入門「10章 要件定義書生成Alエージェントの開発」輪読会スライド
takaakiinada
0
140
AWS全冠芸人が見た世界 ~資格取得より大切なこと~
masakiokuda
4
5.2k
CBになったのでEKSのこともっと知ってもらいたい!
daitak
1
160
Featured
See All Featured
Speed Design
sergeychernyshev
29
890
VelocityConf: Rendering Performance Case Studies
addyosmani
328
24k
Scaling GitHub
holman
459
140k
Fontdeck: Realign not Redesign
paulrobertlloyd
83
5.5k
Done Done
chrislema
183
16k
A designer walks into a library…
pauljervisheath
205
24k
Testing 201, or: Great Expectations
jmmastey
42
7.4k
Intergalactic Javascript Robots from Outer Space
tanoku
270
27k
Agile that works and the tools we love
rasmusluckow
328
21k
Six Lessons from altMBA
skipperchong
27
3.7k
A Tale of Four Properties
chriscoyier
158
23k
Code Reviewing Like a Champion
maltzj
522
40k
Transcript
4DBMBʹΑΔ%%%ϥΠΫͳ ϓϩμΫτ։ൃ φΠϧɾϞόΠϧϑΝΫτϦʔ߹ಉษڧձ φΠϧגࣜձࣾएদܚ৴
ࣗݾհ एদܚ৴ φΠϧגࣜձࣾΤϯδχΞ 5XJUUFSɾ(JUIVCZTIOC ʢ΄ͱΜͲ׆ಈͯ͠·ͤΜʣ ͜͜࠷ۙ4DBMBΛ͍ͬͯ·͢ WJNΛ͍ͬͯ·͢
ࠓճͷϓϩμΫτ։ൃʹ͍ͭͯ
ࠓճͷϓϩμΫτ։ൃͷ݅ • Ϗδωε্ͷཁٻ͕ൺֱతଟذʹΘͨΔ • ؔऀͷϩʔϧଟ͍ – ϓϩμΫτΦʔφʔɺΦϖϨʔλʔɺཧ෦ͳͲ • ظతͳӡ༻͕ݟࠐ·ΕΔ
͜ΕΒͷ݅Λߟྀͯ͠ υϝΠϯۦಈઃܭʢ%%%ʣΛ࠾༻
ࠓճͷʮυϝΠϯۦಈઃܭʯʹ͍ͭͯ • υϝΠϯۦಈઃܭͷίϯηϓτΛऔΓೖΕͯɺ ઃܭ։ൃΛ࣮ࢪ • ඞͣ͠ݪଇ௨ΓͰͳ͍ܗͰ υϝΠϯۦಈઃܭͷίϯηϓτΛ࠾༻
ͳͥ4DBMBͰ%%%ͳͷ͔ʁ • ࣮༻తͳγϯλοΫεͷ؆ܿ͞ – ϞσϧΛ࣮ʹམͱ͢ίετ͕͍ • ܕγεςϜ͕ڧྗ – ੩తܕ͚ʹΑΔܕ҆શੑ ϏδωεϩδοΫ͕ෳࡶͳέʔεͰޮՌత
– ϞσϧΛܕͰදݱ͢Δ͜ͱ͕Ͱ͖Δ
υϝΠϯۦಈઃܭͱ
υϝΠϯۦಈઃܭͱ ιϑτΣΞͷઃܭख๏Ͱ͋ΓɺʮෳࡶͳυϝΠ ϯͷઃܭɺϞσϧϕʔεͰߦ͏͖ʯͰ͋Γɺ ·ͨʮେͷιϑτΣΞϓϩδΣΫτͰɺγ εςϜΛ࣮͢ΔͨΊͷಛఆͷٕज़Ͱͳ͘ɺυ ϝΠϯͦͷͷͱυϝΠϯͷϩδοΫʹযΛஔ ͖͘ʯͰ͋Δͱ͢Δ CZ8JLJQFEJB
ʁʁʁ
͏গ͠Θ͔Γ͘͢
υϝΠϯۦಈͰͳ͍ઃܭͷྫ ࣮ݱ͍ͨ͠ػೳɾݟͨΛܾΊΔ ٕज़બఆઃܭΛߦ͍ɺ ۩ମతͳ࣮ٕज़ͰػೳΛ࣮ݱ͢Δ ͜ΕυϝΠϯͷຊ࣭͕Կͳͷ͔ʁΛ໌Β͔ʹ͓ͯ͠Βͣɺ υϝΠϯۦಈઃܭͰͳ͍
υϝΠϯۦಈઃܭʁ ϏδωεྖҬͷϢϏΩλεݴޠ ʢ౷ҰݴޠʣΛߏங ʮ࣮ݱ͍ͨ͜͠ͱʯʮ࣮ݱ͢Δ͜ͱʯΛ ϢϏΩλεݴޠͰදݱ ϢϏΩλεݴޠͰදݱ͞ΕͨυϝΠϯϞσϧΛ ۩ମతͳ࣮ٕज़Ͱ࣮͢Δ
ϢϏΩλεݴޠʹΑΔ υϝΠϯϞσϧ
ϓϩμΫτ։ൃʹ͓͚ΔݴޠͷִͨΓ ϓϩμΫτΦʔφʔ ։ൃऀ ΫϥΠΞϯτ ΫϥΠΞϯτ
ϓϩμΫτ։ൃʹ͓͚ΔݴޠͷִͨΓ ϓϩμΫτΦʔφʔ ։ൃऀ ΫϥΠΞϯτ ΫϥΠΞϯτ ʮΫϥΠΞϯτʯಉ͡ҙຯʁ
ϢϏΩλεݴޠͰ༻ޠΛ౷Ұ ༻ޠͷఆٛΛ໌֬ʹ͢Δ ސ٬ ͓٬༷ Ϗδωε্ͷΫϥΠΞϯτ ΫϥΠΞϯτ αʔόɾΫϥΠΞϯτϞσϧͷ ΫϥΠΞϯτʢٕज़༻ޠʣ • ౷ҰͷޠኮͰཁ݅ɾ༷ΛܾΊΔ
• ౷ҰޠኮͰද͞ΕͨϏδωε্ͷࣝΛϞσϧԽ͢Δ
౷ҰޠኮͰυϝΠϯͷࣝΛද͢ • ̍ͭͷʮސ٬ʯෳͷʮϓϩδΣΫτʯΛ࣋ͭ • ʮϢʔβʯʮϓϩδΣΫτʯ͝ͱ ʮݖݶʯΛมߋ͢Δ͜ͱ͕Ͱ͖Δ ʮϢʔβʯͱʁʮݖݶʯͱʁͳͲ͕ ໌֬ʹͳ͍ͬͯΔͷͰɺ ʮϢʔβʯʹର͢ΔೝࣝͷζϨੜ͡ͳ͘ͳΔ
υϝΠϯͷࣝΛϞσϧԽ 顧客 プロジェクト ϞσϧΛͲ͏දݱ͢Δ͔ʁͦ͜·ͰॏཁͰͳ͍ Ͳ͏͍͏ϞσϧͰ͋Δ͔ʁΛ νʔϜͷதͰڞ༗Ͱ͖͍ͯΔ͜ͱ͕ॏཁ ϞσϧԽͷྫ
υϝΠϯۦಈΛ࣮ݱ͢Δ ΞʔΩςΫνϟ
ΞʔΩςΫνϟͷཁٻ • υϝΠϯϞσϧ͕ओମʹͳΔ͖ – Ϟσϧ͕ಛఆͷ࣮ٕज़ʹґଘ͍͚ͯ͠ͳ͍ • ٕज़తͳؔ৺ࣄυϝΠϯͷؔ৺ࣄͱ ͞Ε͍ͯΔ͖
ҰൠతͳϨΠϠʔԽΞʔΩςΫνϟ Infrastructure Layer UI & Presenta1on Layer Applica1on Layer Domain
Layer
ҰൠతͳϨΠϠʔԽΞʔΩςΫνϟ Infrastructure Layer UI & Presenta1on Layer Applica1on Layer Domain
Layer υϝΠϯ͕ΠϯϑϥετϥΫνϟ ʢ۩ମతͳ࣮ٕज़ʣʹґଘͯ͠͠·͍ͬͯΔ
࠾༻ͨ͠ΞʔΩςΫνϟ Domain Layer Infrastructure Layer UI & Presenta1on Layer Applica1on
Layer
࠾༻ͨ͠ΞʔΩςΫνϟ Domain Layer Infrastructure Layer UI & Presenta1on Layer Applica1on
Layer υϝΠϯΛ࠷ԼҐͷϨΠϠʔ ΠϯϑϥετϥΫνϟͷར༻͕ඞཁͳՕॴ ͦͷΠϯλʔϑΣΠεΛఏڙ
࠾༻ͨ͠ΞʔΩςΫνϟ Domain Layer Infrastructure Layer UI & Presenta1on Layer Applica1on
Layer ΠϯϑϥετϥΫνϟ࠷্ҐͷϨΠϠʔʹ͠ ԼҐϨΠϠʔͷΠϯλʔϑΣΠεΛ࣮
ΞʔΩςΫνϟΛ࣮ݱ͢Δʹ • ηύϨʔτΠϯλʔϑΣΠε ۩ମతͳ࣮Λ༩͑Δඞཁ͕͋Δ • ޙ͔Β࣮Λ༩͑Δखஈ – %FQFOEFODZ*OKFDUJPO %*
– 4FSWJDF-PDBUPS – ͳͲ • ࠓճ%*Ͱ࣮Λఏڙˠ4DBMBͰʁ
4DBMBʹΑΔ੩త%* trait RepositoryRegistry { val fooRepository: Repo } // fooRepositoryΛ͏Ϋϥε
trait BarService { this: RepositoryRegistry => def doSomething = { fooRepository.fetch } } // ࣮Λ࣋ͭτϨΠτ trait RepositoryRegistryImpl { // Repo࣮ val fooRepository = Repo } // ࣮Λಋೖ class BerServiceImpl extends RepositoryRegistryImpl
4DBMBʹΑΔ੩త%* trait RepositoryRegistry { val fooRepository: Repo } // fooRepositoryΛ͏Ϋϥε
trait BarService { this: RepositoryRegistry => def doSomething = { fooRepository.fetch } } // ࣮Λ࣋ͭτϨΠτ trait RepositoryRegistryImpl { // Repo࣮ val fooRepository = Repo } // ࣮Λಋೖ class BerServiceImpl extends RepositoryRegistryImpl ͜ΕͨͩͷΠϯλʔϑΣΠεʢUSBJUʣ
4DBMBʹΑΔ੩త%* trait RepositoryRegistry { val fooRepository: Repo } // fooRepositoryΛ͏Ϋϥε
trait BarService { this: RepositoryRegistry => def doSomething = { fooRepository.fetch } } // ࣮Λ࣋ͭτϨΠτ trait RepositoryRegistryImpl { // Repo࣮ val fooRepository = Repo } // ࣮Λಋೖ class BerServiceImpl extends RepositoryRegistryImpl ࣗܕΞϊςʔγϣϯͰUSBJUͷґଘΛએݴ
4DBMBʹΑΔ੩త%* trait RepositoryRegistry { val fooRepository: Repo } // fooRepositoryΛ͏Ϋϥε
trait BarService { this: RepositoryRegistry => def doSomething = { fooRepository.fetch } } // ࣮Λ࣋ͭτϨΠτ trait RepositoryRegistryImpl { // Repo࣮ val fooRepository = Repo } // ࣮Λಋೖ class BerServiceImpl extends RepositoryRegistryImpl ͜͜Ͱ۩ମతͳ࣮Λ༩͍͑ͯΔ %*
4DBMBʹΑΔ੩త%* trait RepositoryRegistry { val fooRepository: Repo } // fooRepositoryΛ͏Ϋϥε
trait BarService { this: RepositoryRegistry => def doSomething = { fooRepository.fetch } } // ࣮Λ࣋ͭτϨΠτ trait RepositoryRegistryImpl { // Repo࣮ val fooRepository = Repo } // ࣮Λಋೖ class BerServiceImpl extends RepositoryRegistryImpl ࣮Λಋೖ͢Δલͷஈ֊Ͱ ґଘΛએݴͨ͠USBJUͷϝιου͕͑Δ
4DBMBʹΑΔϞσϧͷ࣮
ϞσϧΛઃܭɾ࣮ʹམͱ͢ • υϝΠϯͷ࣮ • υϝΠϯۦಈઃܭʹ͓͍ͯఆٛ͞Εͨಓ۩Λ ͍4DBMBͷίʔυͰදݱ͢Δ • %%%ͷಓ۩ – &OUJUZ
– 7BMVF0CKFDU – 4FSWJDF – 3FQPTJUPSZ – ͳͲ
ྫɿ7BMVF0CKFDUͷ࣮ • 7BMVF0CKFDU – Λදݱ͢ΔΦϒδΣΫτ – ࣗମʹυϝΠϯ্ͷҙຯΛ࣋ͨͤΔ • ྫɿՁ֨ʢ1SJDFʣ –
ʮԁʯʹؚ·ΕΔཁૉʮʯͱʮԁʯ – 1SJDFͷϞσϧ࣍ͷཁૉΛ࣋ͭ • WBMVF • DVSSFODZ+1:
+BWBʹΑΔ1SJDFΫϥε public class Price { public int value; // Ձ֨ͷ
public Currency currency; // ௨՟ Price(int value, Currency currency) { this.value = value; this.currency = currency; } } // PriceΦϒδΣΫτͷੜ new Price(100, new Currency(JPY))
4DBMBʹΑΔ1SJDFΫϥε case class Price(value: Int, currency: Currency) // case class
ʹΑΓ্هͷҰߦͰදݱग़དྷΔ // ͜Ε͚ͩͰ৽͍͠ΦϒδΣΫτΛੜՄೳ Price(100, JPY)
4DBMBʹΑΔ1SJDFΫϥε case class Price(value: Int, currency: Currency) // case class
ʹΑΓ্هͷҰߦͰදݱग़དྷΔ // ͜Ε͚ͩͰ৽͍͠ΦϒδΣΫτΛੜՄೳ Price(100, JPY) ϞσϧԽ͢Δ࣮ίετ͕ͱͯখ͍͞
ܕύϥϝʔλʹΑΔදݱ trait Tax case object IncludingTax extends Tax
// ੫ࠐ case object ExcludingTax extends Tax // ੫ൈ // ܕύϥϝʔλʢδΣωϦοΫʣʹΑͬͯදݱՄೳ // ATaxͷαϒܕ case class Price[A <: Tax](value: Int, currency: Currency) // 100ԁʢ੫ࠐʣͷදݱ Price[IncludingTax](100, JPY)
ܕύϥϝʔλʹΑΔදݱ trait Tax case object IncludingTax extends Tax
// ੫ࠐ case object ExcludingTax extends Tax // ੫ൈ // ܕύϥϝʔλʢδΣωϦοΫʣʹΑͬͯදݱՄೳ // ATaxͷαϒܕ case class Price[A <: Tax](value: Int, currency: Currency) // 100ԁʢ੫ࠐʣͷදݱ Price[IncludingTax](100, JPY) ੫ൈɾ੫ࠐΛܕύϥϝʔλʹΑͬͯදݱ
ܕύϥϝʔλʹΑΔදݱ // ͷՁ֨੫ࠐͰ͋Δ͜ͱ͕ܕͰදݱग़དྷΔ case class Product( name: String,
price: Price[IncludingTax] ) // ͷදݱྫ Product(“ίοϓຊ”, Price[IncludingTax](4968, JPY)) ͜ͷΑ͏ͳܗͰɺϞσϧΛ؆͔ܿͭܕ҆શʹ ίʔυʹམͱ͍ͯ͘͜͠ͱ͕Մೳ
·ͱΊ
4DBMBʹΑΔ%%%Ͳ͏ͳͷʁ • υϝΠϯۦಈઃܭʹ͓͚Δ4DBMBͷ࠾༻ ʢ࣮ίετɾදݱྗͷ؍ͰʣϝϦοτ͕େ͖͍ • ͨͩ͠ɺͲͷϓϩμΫτʹద͍ͯ͠ΔΘ͚Ͱͳ͍ – ྫ͑ɺϓϩτλΠϓతͳϓϩμΫτʹෆ͖ • ϓϩμΫτʹదͨ͠ઃܭख๏ΛऔΕ͍ͯΔ͔͕
࠷ऴతʹॏཁ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠