「Scala将軍達の後の祭り」での発表資料
http://scala-syogun-matsuri.connpass.com/event/28124/
ScalaͰֶͿϔΩαΰφϧΞʔΩςΫνϟ࣮ફೖ!Scalaক܉ୡͷޙͷࡇΓ@kimutyam2016/03/26
View Slide
ࣗݾհ!!ଜজ@kimutyam2012/4ʹηϓςʔχೖࣾηϓςʔχɾΦϦδφϧͷϦʔυΤϯδχΞΛ୲ͯ͠·͢1લ͔Βࠂͷӡ༻ཧπʔϧʮPYXISʯͷ։ൃΛͬͯ·͢@j5ik2oʹࢣࣄͯ͠ɺScala/DDDΛ1͘Β͍࣮ફ͖ͯͨ͠ਓ!ڵຯൣғDDDTDDϔΩαΰφϧΞʔΩςΫνϟϚΠΫϩαʔϏεΞʔΩςΫνϟ
ScalaͷαϯϓϧΛݩʹ࣮ફతͳϔΩαΰφϧΞʔΩςΫνϟͷΉํʹ͍͓ͭͯ͠·͢
Agenda1. ϨΠϠʔυΞʔΩςΫνϟ͔ΒϔΩαΰφϧΞʔΩςΫνϟ2. ϔΩαΰφϧΞʔΩςΫνϟ֓ཁ3. ฐࣾͰͷιϑτΣΞઓུ
1.ϨΠϠʔυΞʔΩςΫνϟ͔ΒϔΩαΰφϧΞʔΩςΫνϟ
Layered Architecture֓೦ਤUIApplicationDomainInfrastructureDependency
Layered Architecture֓೦ਤUIApplicationDomainInfrastructureDependency• υϝΠϯ͕ΠϯϑϥετϥΫνϟʹґଘ͍ͯ͠Δ
ͦͦΠϯϑϥετϥΫνϟͬͯʁ>্ҐͷϨΠϠΛࢧ͑ΔҰൠతͳٕज़తػೳΛఏڙ͢Δɻ͜ΕʹɺΞϓϦέʔγϣϯͷͨΊͷϝοηʔδૹ৴ɺυϝΠϯͷͨΊͷӬଓԽɺϢʔβʔΠϯλʔϑΣʔεͷͨΊͷΟδΣοτඳըͳͲ͕͋ΔɻΤϦοΫɾΤϰΝϯεͷυϝΠϯۦಈઃܭhttp://urx.blue/sP9dͦͷଞͷҰൠతͳٕज़తػೳͱʁ(ࢲతݟղ)• ݴޠ• ϢʔςΟϦςΟ• ϥΠϒϥϦetc….
υϝΠϯ͕ΠϯϑϥετϥΫνϟʹґଘ͢Δ͜ͱѱʁۃͳɺྫ͑ϝοηʔδૹ৴ɺӬଓԽɺϢʔβʔΠϯλʔϑΣʔεͷͨΊͷΟδΣοτඳըʹ͍ͭͯཁ݅తͰมߋͷͳ͍ٕज़ج൫Ͱ͋Εґଘͯ͠Α͍ɻٕज़ΛΓସ͑ΔՄೳੑ͕͋ΔͷͰ͋Εɺ۩ମతͳΠϯϑϥετϥΫνϟͷ࣮ʹґଘ͍ͯ͠ΔυϝΠϯͷϝϯςφϯεੑ͕Լ͢Δɻ!ϢʔςΟϦςΟݴޠϨϕϧͰ·ͰґଘΛؾʹ͢Δඞཁͳ͍ͱ͑Δɻ
Table Module>Table Moduleσʔλϕʔεͷςʔϒϧʹؔ࿈ͨ͠ϏδωεϩδοΫΛ1ͭͷΤϯςΟςΟΫϥεͱ࣮ͯ͠͠·͢ɻιϑτΣΞཁ͕݅υϝΠϯͷӬଓԽʹಛఆͷσʔλϕʔεʹ͔͠Θͳ͍߹ɺ͜ͷख๏Ͱ͍͍ͱߟ͑ΔυϝΠϯʹ࠷దͳΞʔΩςΫνϟΛߟ͑Δ
தنɾେن։ൃʹ͓͚Δݱ࣮ղ• ओʹI/Oͷٕज़ʹؔͯ͠ೖΕସ͑ͯυϝΠϯʹӨڹ͠ͳ͍Α͏ͳઃܭͰ͋Γ͍ͨ• υϝΠϯϞσϧʹӨڹ͠ͳ͍ϥΠϒϥϦɺݴޠػೳґଘ͍͍ͤͯ͞• ϨΠϠʔυΞʔΩςΫνϟʹ͓͍ͯͷґଘؔͰࢹ͍ͯ͠ΔͷυϝΠϯʹӨڹ͢ΔΑ͏ͳٕज़͕ґଘͯ͠͠·͏ͱ͜Ζʹ͋Δɻ(ྫ͑ɺRepository)※͜ΕҎ߱ͷεϥΠυ߹্ΠϯϑϥετϥΫνϟཁ݅มߋ༨ͷ͋ΔΠϯϑϥετϥΫνϟͱͯ͠ѻ͍·͢ɻ
Layered Architecture(DIP)InfrastructureUIApplicationDomainDependencyDomain͕ͲͷϨΠϠʹґଘ͍ͯ͠ͳ͍
~DIP~ґଘؔٯసͷݪଇ>ʮநʯ࣮ͷৄࡉʹґଘͯ͠ͳΒͳ͍ɻ࣮ͷৄࡉ͕ʮநʯʹґଘ͖͢Ͱ͋Δɻ࣮ફυϝΠϯۦಈઃܭ (Object Oriented SELECTION)>্ҐͷϞδϡʔϧԼҐͷϞδϡʔϧʹґଘͯ͠ͳΒͳ͍ɻͲͪΒͷϞδϡʔϧʮநʯʹґଘ͖͢Ͱ͋Δɻ
DDDͰ࠷্ҐͷϞδϡʔϧυϝΠϯͩͱଊ͑Δͷ͕ࣗવͰɺ্ҐϞδϡʔϧυϝΠϯͷ͜ͱΛࢦ͢ɻ࣮ͷํυϝΠϯͷந(I/F)ʹΑܾͬͯఆ͞ΕΔɻ~DIP~ґଘؔٯసͷݪଇ ࢲతݟղ
~DIP~ґଘؔٯసͷݪଇ!(ݴ͍͑ྫ)υϝΠϯ͕ΠϯϑϥετϥΫνϟʹґଘͯ͠ͳΒͳ͍ɻͲͪΒͷϞδϡʔϧυϝΠϯͷநʹґଘ͖͢Ͱ͋Δɻ!>্ҐͷϞδϡʔϧԼҐͷϞδϡʔϧʹґଘͯ͠ͳΒͳ͍ɻͲͪΒͷϞδϡʔϧʮநʯʹґଘ͖͢Ͱ͋Δɻ
~DIP~ґଘؔٯసͷݪଇ(ݴ͍͑ྫ)υϝΠϯͷநΠϯϑϥετϥΫνϟͷ࣮ͷৄࡉʹґଘͯ͠ͳΒͳ͍ɻΠϯϑϥετϥΫνϟͷ࣮ͷৄࡉ͕υϝΠϯͷநʹґଘ͖͢Ͱ͋Δɻ>ʮநʯ࣮ͷৄࡉʹґଘͯ͠ͳΒͳ͍ɻ࣮ͷৄࡉ͕ʮநʯʹґଘ͖͢Ͱ͋Δɻ
Layered Architecture(DIP)αϯϓϧίʔυ(؆қ)!https://github.com/kimutyam/layered-dip-hands-on
ύοέʔδྫ!ϨΠϠຖʹϓϩδΣΫτׂ
υϝΠϯϓϩδΣΫτ(ྫ)!RepositoryͷI/FΛఆٛ
ΠϯϑϥετϥΫνϟϓϩδΣΫτ(ྫ)!Repositoryͷ࣮
ٕज़͕૿͍͑ͯ͘ʹͭΕͯΠϯϑϥετϥΫνϟ͕ϑΝοτʹͳΓ͕ͪ(ΠϯϑϥετϥΫνϟΛϓϩδΣΫτׂͨ͠Βղܾ)UI͕૿͍͑ͯ͘ʹͭΕͯUI͕ϑΝοτʹͳΓ͕ͪ(UIΛϓϩδΣΫτׂͨ͠Βղܾ)Layered Architecture With DIPΞʔΩςΫνϟϨϕϧͰΠϯϑϥετϥΫνϟͱUIͷؔ৺ͷΛߦ͏͜ͱ͕͍͠
2.ϔΩαΰφϧΞʔΩςΫνϟ֓ཁ
ϔΩαΰφϧΞʔΩςΫνϟ(Hexagonal architecture༁)
ଆͱ֎ଆͷΞμϓλΞϓϦέʔγϣϯͷ֎ଆ!ΞϓϦέʔγϣϯػೳཁ݅υϝΠϯͷϏδωεϩδοΫଆͱ֎ଆͷίϛϡχέʔγϣϯΛࣝผ͢Δϙʔτ
ґଘؔਤ
ॲཧͷྲྀΕ
Hexagonal Architecture༻ޠ(1)• Port(ϙʔτ)ΠϯλʔϑΣʔεΛجૅʹσόΠε(αʔϏε)ؒͷձΛࣝผ͢Δɻϙʔτͷઃܭऀ࣍ୈͰࣗ༝ɻ>ͳʹ͕ϙʔτͰɺͳʹ͕ͦ͏Ͱͳ͍͔ɺ΄ͱΜͲΈͷͩɻ>Θͨ͠ͷબɺ2,3,4ϙʔτͷখ͍͞ࣈΛΉ͕͋ΔɻϔΩαΰφϧΞʔΩςΫνϟ(Hexagonal architecture༁)
Hexagonal Architecture༻ޠ(2)• Adapter(Ξμϓλ)ΠϯλʔϑΣʔεΛ֤σόΠε(αʔϏε)͕ඞཁͱ͢Δ৴߸ʹม͑ΔPort : Adapter = 1 : N>σόΠε͕ඞཁͱ͢Δ৴߸ʹม͑Δɺٯ·ͨવΓɻϔΩαΰφϧΞʔΩςΫνϟ(Hexagonal architecture༁)
Hexagonal Architecture༻ޠ(3)• Primary Port(ϓϥΠϚϦʔϙʔτ)ΞϓϦʔέʔγϣϯΛۦಈ͢Δϙʔτͷ͜ͱΛࢦ͢
Hexagonal Architecture༻ޠ(4)• Secondary Port(ηΧϯμϦʔϙʔτ)ΞϓϦʔέʔγϣϯʹۦಈ͞ΕΔϙʔτͷ͜ͱΛࢦ͢
Hexagonal Architectureͷࢫຯ(1)• ϙʔτ୯ҐͰؔ৺Λ͢Δ͜ͱ͕Մೳ• υϝΠϯΛத৺ʹஔ͘ࣄͰΞϓϦέʔγϣϯશମͷํ͕ܾఆ͞ΕΔϙʔτؒͰͷґଘͳ͘ɺϙʔτ্ͰυϝΠϯͳ͍͠ΞϓϦέʔγϣϯͷ࣮Λར༻ͨ͠ΓɺI/FΛ࣮͢Δ• Ξμϓλ୯ҐͰٕज़ͷΈସ͕͑Մೳ(ৄࡉͷٕज़Λมߋͯ͠υϝΠϯʹӨڹ͠ͳ͍)• ϞοΫԽ͍͢͠(ϞοΫDBΛར༻͢ΔΑ͏ͳΈ͕؆୯ʹ࣮ݱͰ͖Δ)• ࢹ֮తͰॲཧͷϑϩʔґଘ͕ؔ໌ྎ
Hexagonal Architectureαϯϓϧίʔυhttps://github.com/kimutyam/hexagonal-hands-on
ύοέʔδྫྫʹΑͬͯϨΠϠɾϙʔτຖʹϓϩδΣΫτׂ
υϝΠϯϓϩδΣΫτྫ(1)• ίΞυϝΠϯͱαϒυϝΠϯΛू• ڥք͚ͮΒΕͨίϯςΩετؒͷґଘΛͳ͘͢• υϝΠϯҎ֎ͷϓϩδΣΫτͷґଘͤ͞ͳ͍
υϝΠϯϓϩδΣΫτྫ(2)• υϝΠϯϞσϧ(Entity,VO,Service,Event,Module)• Repository,Factory,Aggregate etc
υϝΠϯϓϩδΣΫτྫ(2)
ΞϓϦέʔγϣϯϓϩδΣΫτྫ(1)ΞϓϦέʔγϣϯϓϩδΣΫτ֤υϝΠϯΛґଘͤ͞Δ
ΞϓϦέʔγϣϯϓϩδΣΫτྫ(2)• ΞϓϦέʔγϣϯαʔϏεࠞཚ͕ͪ͠ͳαʔϏεͱ͍͏֓೦ʹ͍ͭͯυϝΠϯαʔϏεͱΞϓϦέʔγϣϯαʔϏεͷҧ͍ʹ͍ͭͯҎԼࢀর
ΞϓϦέʔγϣϯϓϩδΣΫτྫ(3)ڥք͚ͮΒΕͨυϝΠϯίϯςΩετͷConverter(Mapper)
ΞϓϦέʔγϣϯϓϩδΣΫτྫ(4)DTO(Data Transfer Object)
ϙʔτϓϩδΣΫτྫ(1)• ϙʔτϓϩδΣΫτϓϥΠϚϦʔϙʔτͱηΧϯμϦϙʔτΛू• ϓϥΠϚϦʔϙʔτ• ηΧϯμϦʔϙʔτ!※ϙʔτؒͷґଘͳ͠
ϓϥΠϚϦʔϙʔτϓϩδΣΫτྫ(1)• WebServiceϙʔτ• HttpʹΑͬͯۦಈ͞ΕΔ• PlayFrameworkΛར༻
ϓϥΠϚϦʔϙʔτϓϩδΣΫτྫ(2)• WebServiceϙʔτ• Controller• Router• json• Form
ϓϥΠϚϦʔϙʔτϓϩδΣΫτྫ(3)• Batchϙʔτ• CLIͰ࣮ߦ͢Δ
ϓϥΠϚϦʔϙʔτϓϩδΣΫτྫ(4)• Batchϙʔτ• Batch• Scheduler etc…
• Persistenceϙʔτ• RDBMSKVSͷӬଓԽͷηΧϯμϦϙʔτϓϩδΣΫτྫ(1)• ThirdPartyAPIϙʔτ• ThirdPartyͷAPIΛܦ༝ͨ͠ίϛϡχέʔγϣϯΛ͢Δ
• Persistenceϙʔτ• RDBMSKVSͷ۩ମతͳ࣮• υϝΠϯϦϙδτϦI/Fͷํʹै͏• DAOηΧϯμϦϙʔτϓϩδΣΫτྫ(2)
• ThirdPartyAPIϙʔτ• APIClient• υϝΠϯϦϙδτϦI/Fʹै࣮ͬͨηΧϯμϦϙʔτϓϩδΣΫτྫ(3)
• ֤ϓϩδΣΫτΛूɾґଘ• ·ͱΊRootϓϩδΣΫτྫ(1)
• DependencyInjection• ΞϓϦέʔγϣϯͷઃఆϑΝΠϧRootϓϩδΣΫτྫ(2)
Hexagonal Architectureͷࢫຯ(2)ϔΩαΰφϧΞʔΩςΫνϟෳͷ֎෦αʔϏεͱͷ࿈ܞ͕࣮͍͢͠ํத৺ʹυϝΠϯΛਾ͑Δɹˠɹ౷ҰతͳઃܭΛҡ࣋͢Δ͜ͱ͕Մೳ
3.ฐࣾͰͷιϑτΣΞઓུ
ฐࣾͰߦ͍ͬͯΔઓུઓུతυϝΠϯઃܭઓज़తυϝΠϯઃܭৄࡉ࣮ϞοΫ࣮ϞϊϦγοΫΞϓϦέʔγϣϯ
ฐࣾͰߦ͍ͬͯΔઓུઓུతυϝΠϯઃܭઓज़తυϝΠϯઃܭৄࡉ࣮ϞοΫ࣮ઓུతυϝΠϯઃܭઓज़తυϝΠϯઃܭৄࡉ࣮ϞοΫ࣮ڥք͚ͮΒΕͨίϯςΩετ୯ҐͰϚΠΫϩαʔϏεԽ
ϚΠΫϩαʔϏεΞʔΩςΫνϟͷΠϝʔδ!
࣮ફೖͯ͠ΈͯͷϝϦοτ·ͱΊ• ϓϩδΣΫτɾϓϩμΫτಋೖظͷυϝΠϯΛৠཹͤ͞ͳ͕ΒɺϞοΩϯά͕͍͢͠• ґଘؔͷ੍͕ڧ͍ΞʔΩςΫνϟͳͷͰίʔυͷํ͕ͿΕͮΒ͍• ৽͍ٕ͠ज़Λಋೖ͍͢͠• ϚΠΫϩαʔϏεͱͷ૬ੑ͕Α͍• ϨΠϠʔυΞʔΩςΫνϟDIPͱൺͯؔ৺ͷ͕͘͢͠• ΞʔΩςΫνϟਤͷࢹ֮ޮՌʹΑΓϝϯόʔͷཧղ͕͍!!
࣮ફೖͯ͠ΈͯΜͩ͜ͱ·ͱΊ• Batchͷ։ൃΛBatchϙʔτͰߦ͍͕ͬͯͨɺඞͣ͠υϝΠϯΛܦ༝͢ΔBatchͰͳ͔ͬͨɻ (MySQLͷύʔςΟγϣϯՃͱ͔)→ɹRootϓϩδΣΫτͷઃఆͱͯ͠ఆ͍ٛͯ͠Δ→ɹͦΕΑ͏ͷϓϩδΣΫτΛΔͷ͋Γͩͱߟ͑Δ!• ϙʔτؒͷίϛϡχέʔγϣϯ͕Ͱ͖ͳ͍ͷͰɺͪΐͬͱ࣮ͨ͠Λॻ͘ͱ͖ͰυϝΠϯܦ༝Ͱ࣮ݱΛߟ͑Δඞཁ͕͋ͬͨ→ɹ͍͍ҙຯͰѱ͍ҙຯͰ੍͕͋ΓɺΞτϓοτ͕͘ͳΔέʔε͕͋Γ·͢ɻ׳ΕΕͳΜͯ͜ͱͳ͍Ͱ͕͢ɻ
ࢀߟࢿྉॻ੶ ʰ࣮ફυϝΠϯۦಈઃܭ (Object Oriented SELECTION)ʱॻ੶ʰΤϦοΫɾΤϰΝϯεͷυϝΠϯۦಈઃܭʱϔΩαΰφϧΞʔΩςΫνϟͱϨΠϠʔΞʔΩςΫνϟͷҧ͍ͱϚΠΫϩαʔϏε - falsandtruͷϝϞாυϝΠϯʹ࠷దͳΞʔΩςΫνϟΛߟ͑ΔϔΩαΰφϧΞʔΩςΫνϟ(Hexagonal architecture༁)ΦϒδΣΫτࢥߟ: ґଘؔٯసͷݪଇࠞཚ͕ͪ͠ͳαʔϏεͱ͍͏֓೦ʹ͍ͭͯ
͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠