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
510
ScalaによるDDDライクなプロダクト開発
2016/5/23 モバイルファクトリーさんとの勉強会で話したスライド
Yoshinobu Wakamatsu
May 23, 2016
Tweet
Share
More Decks by Yoshinobu Wakamatsu
See All by Yoshinobu Wakamatsu
金融領域におけるサービス開発の進め方
yshnb
0
720
資産運用スタートアップの開発で採用した、PlayによるClean Arcitectureでの設計・開発事例
yshnb
5
980
ReactベースのSPA開発で開発者が気をつけたいSEOのお話
yshnb
2
1.8k
Fundsのアーキテクチャについて
yshnb
0
260
Applivの開発体制から考える、理想の開発体制とは?
yshnb
2
10k
Other Decks in Technology
See All in Technology
『星の世界の地図の話: Google Sky MapをAI Agentでよみがえらせる』 - Google Developers DevFest Tokyo 2025
taniiicom
0
120
OSだってコンテナしたい❗Image Modeが切り拓くLinux OS運用の新時代
tsukaman
0
120
Kubernetesと共にふりかえる! エンタープライズシステムのインフラ設計・テストの進め方大全
daitak
0
420
Dev Containers と Skaffold で実現する クラウドネイティブ開発環境 ローカルのみという制約に挑む / Cloud-Native Development with Dev Containers and Skaffold: Tackling the Local-Only Constraint
bitkey
PRO
0
120
2025年 面白の現在地 / Where Omoshiro Stands Today: 2025
acidlemon
0
260
FFMとJVMの実装から学ぶJavaのインテグリティ
kazumura
0
160
Redux → Recoil → Zustand → useSyncExternalStore: 状態管理の10年とReact本来の姿
zozotech
PRO
21
8.9k
自然言語でAPI作業を片付ける!「Postman Agent Mode」
nagix
0
120
AI × クラウドで シイタケの収穫時期を判定してみた
lamaglama39
1
380
メッセージ駆動が可能にする結合の最適化
j5ik2o
8
1.1k
【M3】攻めのセキュリティの実践!プロアクティブなセキュリティ対策の実践事例
axelmizu
0
180
Perlの生きのこり - YAPC::Fukuoka 2025
kfly8
0
750
Featured
See All Featured
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1k
How GitHub (no longer) Works
holman
315
140k
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
52
5.7k
How to train your dragon (web standard)
notwaldorf
97
6.4k
Optimising Largest Contentful Paint
csswizardry
37
3.5k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.1k
Building Adaptive Systems
keathley
44
2.8k
The Straight Up "How To Draw Better" Workshop
denniskardys
239
140k
Faster Mobile Websites
deanohume
310
31k
Practical Orchestrator
shlominoach
190
11k
Become a Pro
speakerdeck
PRO
29
5.6k
Java REST API Framework Comparison - PWX 2021
mraible
34
9k
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ͷ࠾༻ ʢ࣮ίετɾදݱྗͷ؍ͰʣϝϦοτ͕େ͖͍ • ͨͩ͠ɺͲͷϓϩμΫτʹద͍ͯ͠ΔΘ͚Ͱͳ͍ – ྫ͑ɺϓϩτλΠϓతͳϓϩμΫτʹෆ͖ • ϓϩμΫτʹదͨ͠ઃܭख๏ΛऔΕ͍ͯΔ͔͕
࠷ऴతʹॏཁ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠