Slide 1

Slide 1 text

ͦΕ͔Β$234Ͱ࣮૷͢Δ +BOVBSZ  ·ͣ͸υϝΠϯʹ޲͖߹ͬͯ ,PTVLF"CF

Slide 2

Slide 2 text

"CPVU.F ,PTVLF"CF גࣜձࣾ%JHJUUMF$50 ❤🏋🚴 !NFNFUJDT

Slide 3

Slide 3 text

TRITON 2023.10.25 %JHJUUMFJOD Τϯλϝۀք޲͚ʹσδλϧάοζɺ "*ٕज़Λ׆༻ͨ͠ίϛϡχέʔγϣϯ αʔϏεͳͲɺΠϯλϥΫςΟϒͳମ ݧΛ࣮ݱ͢ΔαʔϏεΛ૑ग़͢Δ

Slide 4

Slide 4 text

εςʔΫϗϧμʔͷ૝૾Λ௒͑ΔͨΊʹɺΤϯδχ Ξ΋ϓϩμΫτσβΠϯʹίϛοτ͢Δɻਖ਼͍͠ ΞʔΩςΫνϟύλʔϯͰɺؒҧͬͨϓϩμΫτΛ ࡞Δ͜ͱ͸ආ͚͍ͨɻ &SJD&WBOT %PNBJO%SJWFO%FTJHO5BDLMJOH$PNQMFYJUZJOUIF)FBSUPG4PGUXBSF 'JSTUBOEGPSFNPTU ϓϩμΫτσβΠϯ ʹ࣠଍Λஔ͘ ιϑτ΢ΣΞͷ֩৺͸ɺυϝΠϯʹؔ܎ͨ͠໰୊Λ ϢʔβʔͷͨΊʹղܾ͢ΔೳྗͰ͋Δɻ ͦΕҎ֎ͷಛ௃͸͍ͣΕ΋ɺͲΕ΄Ͳॏཁͩͱͯ͠΋ɺ ͜ͷجຊతͳ໨తΛࢧ͑Δʹ͗͢ͳ͍ɻ

Slide 5

Slide 5 text

$234͸ΞʔΩςΫνϟύλʔϯͷҰछ͕ͩɺ ϓϩμΫτσβΠϯͷώϯτ͕຾͍ͬͯΔ ɾ.7$ ɾϨΠϠʔυΞʔΩςΫνϟ ɾΠϕϯτιʔγϯά ɾFUDʜ ɾϢʔβʔ΍υϝΠϯͷ෼ੳ ɾ֓೦Ϟσϧ ɾ69ઃܭ ɾFUDʜ ΞʔΩςΫνϟύλʔϯ ϓϩμΫτσβΠϯ #VU 8IZ$234 ιϑτ΢ΣΞͷ಺෦Λମܥతʹ੔ཧ͢Δํ๏ ϢʔβʔχʔζʹରԠ͢Δ੡඼Λ࡞੒͢Δϓϩηε

Slide 6

Slide 6 text

ϢϏΩλεݴޠͷಈࢺ͕$36%ʹऩଋ͢Δ͜ͱ͸͋·Γͳ͍ ΦϒδΣΫτͷߏ଄΍ؔ܎ੑ͸͋Δ͕ɺৼΔ෣͍ͷͳ͍ʮυϝΠϯϞσϧශ݂঱ʯ σʔλͷ$36%͕த৺ͷΞʔΩςΫνϟͰ͸ɺυϝΠϯۦಈઃܭ͕ෆՄೳ Ϣʔβʔମݧ͕$36%ʹҾ͖ͣΒΕΔͷ͸ɺ༨ܭʹѱ͍ (SFH:PVOH $234EPDVNFOUTCZ(SFH:PVOH "TUFSFPUZQJDBMFYBNQMFPGUIJTXPVMECFXIFODIBOHJOHUIFTFYPGBOFNQMPZFF ZPVNVTUBGUFSHPFEJUUIFJSIFBMUIJOTVSBODFJOGPSNBUJPO 5IJTJTGBSXPSTFUIBOUIFDSFBUJPOPGBOBOFNJDNPEFM UIJTJTUIFDSFBUJPOPGBHMPSJ fi FE FYDFMTQSFBETIFFU %PNBJO%SJWFO%FTJHO

Slide 7

Slide 7 text

$36%ࢤ޲ͷ6*ʹ͸ɺϢʔβʔͷҙਤ͕૊Έࠐ·Ε͍ͯͳ͍ γεςϜ͕ϢʔβʔͷҙਤΛϩετͯ͠͠·͏ͱɺ໾ཱͭϨϙʔςΟϯά৘ใΛఏڙͰ͖ͳ͍ ֓೦ϞσϧΛਂ͘ཧղ͠ͳ͍ͱ࢖͑ͳ͍ 6TFS*OUFSGBDF ҙਤͷ໌֬Խ

Slide 8

Slide 8 text

$234 $234͸ΦϒδΣΫτΛίϚϯυͱΫΤϦʹ෼཭͢Δ୯७ͳΞʔΩς Ϋνϟύλʔϯ͕ͩɺͦͷԸܙΛे෼ʹड͚ΔͨΊʹ·ͣɺϢʔβʔ ͷҙਤΛ἞ΈऔΓɺମݧʹؾΛ഑Δ (SFH:PVOH $234 5BTL#BTFE6*T &WFOU4PVSDJOHBHI $234JTTJNQMZUIFDSFBUJPOPGUXPPCKFDUTXIFSFUIFSFXBTQSFWJPVTMZPOMZPOF5IF TFQBSBUJPOPDDVSTCBTFEVQPOXIFUIFSUIFNFUIPETBSFBDPNNBOEPSBRVFSZ UIFTBNF EF fi OJUJPOUIBUJTVTFECZ.FZFSJO$PNNBOEBOE2VFSZ4FQBSBUJPO BDPNNBOEJTBOZ NFUIPEUIBUNVUBUFTTUBUFBOEBRVFSZJTBOZNFUIPEUIBUSFUVSOTBWBMVF 

Slide 9

Slide 9 text

ݴޠతͳҙຯ͔Βߟ͑Δͱɺ γεςϜ໋͕ྩΛڋ൱Ͱ͖Δ͜ͱΛ͍ࣔͯ͠Δ $PNNBOE ڋ൱ΛͨͩͷΤϥʔͱͯ͠ѻΘͣɺϢʔβʔମݧͱͯ͠ઃܭʹ৫ΓࠐΜͰ͓͘ ϢʔβʔͷҙਤΛࣽ٧ΊΔͱಉ࣌ʹɺڋ൱͞ΕΔཧ༝ΛΑ͘ߟ͑Δ

Slide 10

Slide 10 text

ݴޠతͳҙຯ͔Βߟ͑Δͱɺ ࣄ࣮͸औΓফͤͳ͍͜ͱΛ͍ࣔͯ͠Δ ΤϰΝϯεຊͰ͸มߋΛӬଓԽ͢Δํ๏͕ᐆດ͕ͩͬͨɺΠϕϯτͰิ׬͞Εͨ &WFOU ͢Ͱʹى͖ͨ͜ͱΛڋ൱͢Δͷ͸ෆࣗવͰ͋ΓɺίϚϯυͱҙຯతͳରশੑ͕͋Δ

Slide 11

Slide 11 text

ٕज़తʹ͸ͲͪΒ΋୯७ͳߏ଄ମͱ͍͏఺Ͱಉ͡Ͱɺ໋໊ํ๏ʹҧ͍͕͋Δ ݴޠతͳҙຯʹ஫໨͠ɺ υϝΠϯϞσϧͱϢϏΩλεݴޠͷ୳ࡧʹ࢖͏ type DeactivateInventoryItem struct { InventoryItemID string Comment string } type InventoryItemDeactivated struct { InventoryItemID string Comment string } &%"΋ɺΠϕϯτʹ࣍ͷࢦؚ͕ࣔ·Εͳ͍ҙຯతͳཧ༝Ͱૄ݁߹ʹͳΔ $PNNBOE&WFOU

Slide 12

Slide 12 text

ΠϕϯτετʔϛϯάΛɺσβΠϯͷख๏ͱͯ͠׆༻͢Δ ҟͳΔόοΫάϥ΢ϯυΛ࣋ͭਓͷߟ͑Λൃࢄͤ͞ɺΧϥʔύζϧͱର࿩Λ௨ͯ͠߹ҙͤ͞Δ ·ͣ͸໰୊Λ޿͘୳ΓɺͦΕ͔Βղܾ΁ऩଋ͍ͤͯ͘͞఺ͰɺσβΠϯࢥߟʹΑ͘ࣅ͍ͯΔ Πϕϯτ ϙϦγʔ ू໿ ίϚϯυ ίϚϯυ Πϕϯτ ू໿ %PO/PSNBO 5IF%FTJHOPG&WFSZEBZ5IJOHT ൴Β͸ɺຊ౰ͷ໰୊͕Կ͔ΛݟఆΊΔ·Ͱ͸ղܾΛ୳ͦ͏ͱ͠ͳ͍ɻ ໰୊͕ఆ·ͬͨͱ͖Ͱ͑͞ɺ໰୊Λղܾ͠Α͏ͱ͸͠ͳ͍ɻ ൴Β͸ཱͪࢭ·ͬͯ޿͍ൣғ͔ΒՄೳͳ౴͑Λ୳͢ɻͦ͏ͯ͠ॳΊͯɺ࠷ऴతʹ൴ΒͷఏҊΛऩଋ͍ͤͯ͘͞ɻ ͜ͷϓϩηε͸σβΠϯࢥߟͱݺ͹Ε͍ͯΔɻ &WFOU4UPSNJOH

Slide 13

Slide 13 text

ಉҰू໿ʹର͢Δಉ࣮࣌ߦͰෆม৚͕݅ഁΒΕͳ͍Α͏ʹ͢Δඞཁ͕͋Δ "HHSFHBUF ࡏݿ͕֬ อ͞Εͨ ࡏݿ ࡏݿΛ֬ อ͢Δ ෆม৚݅Λڧ੍͢Δൣғɺͭ·ΓҰ؏ੑͱಉ࣮࣌ߦੑͷ୯Ґ ॲཧ଴ͪ΍ࣦഊͷ૿ՃʹΑΔϢʔβʔମݧͷѱԽʹ஫ҙ͢Δ ࡏݿ͕ϚΠφεʹͳΒͳ͍͜ͱ͸ෆม৚݅ʹͰ͖Δ͔ʁ

Slide 14

Slide 14 text

Πϕϯτൃੜ΍࣌ؒܦաͰىಈ͢ΔϦΞΫςΟϒϩδοΫɺΠϕϯτͱίϚϯυͷؒʹ͋Δࢵ৭ͷ෇ᝦ 1PMJDZ ࡏݿ͕ϚΠ φεͷ৔߹ ೖՙ଴ͪΛ ͢Δ ೖՙ଴͕ͪ ͞Εͨ ೖՙ଴ͪ ू໿ͷෆม৚݅Ͱ͸ͳ͍ɺൺֱతΏΔ΍͔ͳϏδωε্ͷҙࢥܾఆ ࡏݿ͕֬อ ͞Εͨ ࡏݿ ࡏݿΛ֬อ ͢Δ ࡏݿ͕֬อ ͞Εͨ ࡏݿ ࡏݿΛ֬อ ͢Δ Ұ୴ࡏݿͷϚΠφεΛڐ༰ͯ͠ɺʮͦΕ͔Βʯೖՙ଴ͪͷରԠΛ͢Δ

Slide 15

Slide 15 text

஫จ͞Εͨ ஫จ͞Εͨ Βඞͣ ஫จ ஫จ͢Δ υϦϯΫΛ ࡞Δ υϦϯΫ υϦϯΫ͕ ࡞ΒΕͨ υϦϯΫ͕ ׬੒ͨ͠Β ඞͣ ٬ͷ໊લΛ ݺͿ ࢧ෷͍Λ͢ Δ ࢧ෷͍ ࢧ෷͍͕׬ ྃͨ͠ ࢧ෷͍Ͱ͖ ͳ͔ͬͨ৔ ߹͸ υϦϯΫΛ ࣺͯΔ ஫จ͢Δ ࢧ෷͍υ ϦϯΫ࡞੒ ࢧ෷͍υ ϦϯΫ࡞੒ ׬ྃ "HHSFHBUF1PMJDZ ੍໿ΛकΓͳ͕ΒɺॊೈͰϊϯϒϩοΩϯάͳΠϯλϥΫγϣϯΛߟ͑Δ (SFHPS)PIQF 4UBSCVDLT%PFT/PU6TF5XP1IBTF$PNNJU XFDBOTFFUIBUUIFSFBMXPSMEJTPGUFOBTZODISPOPVT 0VSEBJMZMJWFTDPOTJTUTPGNBOZDPPSEJOBUFE CVUBTZODISPOPVTJOUFSBDUJPOT %#ϩοΫ͢Ε͹͍͍ɺͱٕज़ओಋͰߟ͑ͳ͍Α͏ʹ͢Δ

Slide 16

Slide 16 text

ڭՊॻͷ໰୊͸ύλʔϯͷֶशʹ࠷దԽ͞Ε͍ͯΔ͕ɺݱ࣮ʹى͖͍ͯΔ໰୊͸ͦΕͱશ͘ҟͳ͍ͬͯΔ ڭՊॻͷ໰୊Λղ͚ͩ͘Ͱͳ͘ɺݱ࣮ͷ໰୊Λ۷ΓԼ͛Δ ֶशͨ͠ख๏Λɺݱ࣮ͷ໰୊ʹͦͷ··౰ͯ͸Ίͯ΋͏·͍͔͘ͳ͍͜ͱ͕ଟ͍ 5BDLMJOH3FBM*TTVFT ݱ࣮ͷੈքͰ͸ɺ໰୊͸͖Ε͍Ͱ͖ͬͪΓͨ͠แ૷ʹแ·Εͯ͸͜ͳ͍ɻ໰୊͸ൃݟ͞Εͳ͚Ε͹ͳΒͳ͍ɻ ਓ͸ɺຊ෺ͷ໰୊ʹͨͲΓண͘Α͏ʹ۷ΓԼ͛Δ͜ͱΛͤͣʹɺ͋·Γʹ΋҆қʹද໘্ͷ໰୊Λݟͯ͠·͏ͷͩɻ %PO/PSNBO 5IF%FTJHOPG&WFSZEBZ5IJOHT

Slide 17

Slide 17 text

αϒεΫొ࿥͍ͯ͠Δސ٬ʹ͚ͩɺ ίϛϡχςΟ ΞʔςΟετ΍࡞඼ ͷݶఆ౤ߘΛݟ͍ͤͨ 3FBM%PNBJO'BOEPN$PNNVOJUZ

Slide 18

Slide 18 text

঎඼ͷ஫จ͕ ׬ྃͨ͠ ஫จ ঎඼ͷ஫จΛ ׬ྃͤ͞Δ αϒεΫϦϓ γϣϯొ࿥͢ Δ αϒεΫ঎඼ ͷ৔߹ αϒεΫϦϓ γϣϯొ࿥͞ Εͨ αϒεΫϦϓ γϣϯ ౤ߘ͕ ެ։͞Εͨ ౤ߘ ౤ߘΛ ެ։͢Δ ސ٬ ίϛϡχςΟ ؅ཧऀ ސ٬༻ͷ ౤ߘϏϡʔ 'JSTU.PEFM

Slide 19

Slide 19 text

ձ࿩ͷதͰݴ͍͍ͨ͜ͱΛ͏·͘ݴ༿ͰදݱͰ͖ͳ͍ ݶఆ౤ߘΛݟΕΔ͔൑ఆ͢ΔͨΊʹɺຖճܾࡁঢ়ଶΛνΣοΫ͠ͳ͍ͱ͍͚ͣɺίʔυ͕൥ࡶ 6*্Ͱʮࣗ෼͕αϒεΫϦϓγϣϯ͍ͯ͠ΔίϛϡχςΟʯΛͲ͏දݱ͢Ε͹͍͍͔ෆ໌ྎ "XLXBSE$POWFSTBUJPO 6* BOE$PEF ͗ͪ͜ͳ͞ͱ͍͏঱ঢ়

Slide 20

Slide 20 text

νΣοΫΠϯ͢Δͱ͖ɺʮαϒεΫʯͱ͍͏ࢧ෷͍ܖ໿Λ౎౓֬ೝͯ͠΋Β͍ͬͯΔΘ͚Ͱ͸ͳ͍ ՝ۚΛࡁ·ͤͨΒʮձһূʯΛड͚औ͍ͬͯΔ 'PDVTPO%PNBJOBOE6TFS ਓؒͷ׆ಈͱɺͦ͜Ͱى͖͍ͯΔίτʹ஫໨͢Δ

Slide 21

Slide 21 text

঎඼ͷ஫จ͕ ׬ྃͨ͠ αϒεΫ঎඼ ͷ৔߹ ஫จ ঎඼ͷ஫จΛ ׬ྃͤ͞Δ αϒεΫϦ ϓγϣϯొ ࿥͢Δ αϒεΫϦϓ γϣϯొ࿥͞ Εͨ αϒεΫϦϓ γϣϯ ౤ߘ͕ ެ։͞Εͨ ౤ߘ ౤ߘΛ ެ։͢Δ ސ٬ ίϛϡχςΟ ؅ཧऀ ސ٬༻ͷ ౤ߘϏϡʔ αϒεΫϦϓ γϣϯొ࿥͞ ΕͨΒ ձһূΛड ͚औΔ ձһূ͕ड͚ औΒΕͨ ձһূ ձһূ ձһূ͕ఀࢭ ͞Εͨ ձһূΛఀ ࢭ͢Δ αϒεΫϦ ϓγϣϯΛ ແޮԽ͢Δ αϒεΫϦϓ γϣϯ͕ແޮ Խ͞Εͨ αϒεΫϦϓ γϣϯ αϒεΫϦϓ γϣϯ͕ແޮ Խ͞ΕͨΒ ސ٬ αʔϏε΁ͷࢧ෷͍ͱར༻ͷݖརΛ෼཭͠ɺ ձһূΛड͚औͬͨɺͱ͍͏ࣄ࣮Λ௥Ճ 3FDPOTJEFS%PNBJO.PEFM

Slide 22

Slide 22 text

3FDPOTJEFS6TFS&YQFSJFODF ձһূΛϦονͳΧʔυσβΠϯͰϢʔβʔʹݟͤΔ͜ͱͰɺॴ༗ײ΍ؼଐײΛߴΊΔମݧʹ ඞཁʹԠͯ͡ɺαϒεΫͳ͠ͰձһূΛ෇༩͢Δ͜ͱ΋Մೳʹͳͬͨ υϝΠϯϞσϧͷมԽ͕ϢʔβʔମݧΛมԽͤ͞Δ ظؒݶఆͷΧʔυσβΠϯͳͲɺ৽͍͠Ձ஋Λߟ͑ΔͨΊͷ଍৔ʹͳΔ

Slide 23

Slide 23 text

υϝΠϯΤΩεύʔτ͸αϒεΫʹΑΔ҆ఆऩӹΛୈҰʹߟ͍͑ͯͨɻυϝΠϯΤΩεύʔτ͸ݸผʹಛԽͨ͠஌ࣝΛ ͍࣋ͬͯΔ͕ɺશମ࠷దͷղܾࡦΛ͍࣋ͬͯΔΘ͚Ͱ͸ͳ͍ υϝΠϯʹ౿ΈࠐΜͰɺղܾࡦΛ૑଄͢Δ %FTJHO%PNBJO.PEFM &SJD&WBOT %PNBJO%SJWFO%FTJHO5BDLMJOH$PNQMFYJUZJOUIF)FBSUPG4PGUXBSF զʑͷϞσϧ͸ɺ͜ͷϏδωεʹ͸;͞Θ͘͠ͳ͍ํ๏Ͱɺ ϑΝγϦςΟͷ෼୲཰ͱϩʔϯͷ෼୲཰Λ݁ͼ͚͍ͭͯͨͷͰ͋Δɻ தུ  ϑΝγϦςΟ΍ϩʔϯͷγΣΞʹؔͯ͠ɺಛผͳΦϒδΣΫτ͸΋͏ͳ͘ͳͬͨɻ ͲͪΒ΋ɺΑΓ௚ײతʹΘ͔ΔʮγΣΞύΠʯʹׅΓग़͞Εͨͷͩɻ ٕज़ྗͱ૑଄ྗͰɺࣗ෼ͨͪͳΓͷʮγΣΞύΠʯΛൃݟ͢Δ

Slide 24

Slide 24 text

ίϚϯυɺΠϕϯτɺू໿ɺϙϦγʔͱ͍ͬͨ֓೦Λ࣮૷͢Δ͕ɺ CQRS+ES ͸࢖Θͳ͍ 6EJ%BIBO IUUQTYDPN6EJ%BIBOTUBUVT %POU$234 /PUBTBUPQMFWFMBSDIJUFDUVSF /PUVOUJMZPVWFUBTLPSJFOUFEZPVS6* /PUVOUJMZPVWFTFQBSBUFQSJWBUFEBUB fl PXTGSPNQVCMJD"OEJGUIFOFXQSPKFDUJTUSVMZ HSFFO fi FME EF fi OJUFMZEPOU$234 BTZPVQSPCBCMZXPOUCFBCMFUPBEESFTT "SDIJUFDUVSF%FDJTJPO

Slide 25

Slide 25 text

"SDIJUFDUVSF$IBSBDUFSJTUJDT $234 &4͸ɺύϑΥʔϚϯεͱεέʔϥϏϦςΟʹد༩͢Δ ίϚϯυͱΫΤϦΛݸผʹ࠷దԽͰ͖ΔͷͰɺϋΠτϥϑΟοΫ͔ͭڝ߹͕ى͖΍͍͢ྖҬʹ޲͘ (SFH:PVOH $234EPDVNFOUTCZ(SFH:PVOH 5IFCPUUMFOFDLJOUFSNTPGTDBMJOHJTUIFEBUBTUPSBHF8IFOVTJOHB3%#.4BT  DVSSFOUMZVTFUIJTCFDPNFTFWFONPSFPGBQSPCMFNNPTU3%#.4BSFBUUIJTQPJOUOPU IPSJ[POUBMMZTDBMBCMFBOEWFSUJDBMMZTDBMJOHCFDPNFTQSPIJCJUJWFMZFYQFOTJWFWFSZRVJDLMZ Πϕϯτόʔδϣχϯά΍ू໿ڥքมߋͷස౓͕ߴ͍ෆ҆ఆͳྖҬͰ͸มߋίετΛճऩ͢Δͷ͕೉͍͠

Slide 26

Slide 26 text

݁Ռ੔߹ͷΫΤϦ͸Ϣʔβʔମݧʹ௚઀తͳӨڹ͕͋Δ ࠷৽Ͱͳ͍σʔλΛݟ͍ͯΔՄೳੑΛɺϢʔβʔମݧʹંΓࠐΜͰ͓͘ઃܭίετͷલ෷͍͕ඞཁ ໌Β͔ʹεέʔϥϏϦςΟ͕ඞཁͳΒɺϦʔυϨϓϦΧΛޙ͔Βܧ͗઀͗ͰೖΕΔΑΓྑͦ͞͏ &WFOUVBMMZ$POTJTUFOU2VFSZ

Slide 27

Slide 27 text

Collaborative Domain Independent Domain 1VCMJD%BUB ঎඼Ձ֨ 1SJWBUF%BUB ঎඼໊ ঎඼આ໌ ঎඼ը૾ CRUD, Stereotype Architecture CQRS+ES Publish Data 6EJ%BIBO IUUQTYDPN6EJ%BIBOTUBUVT 1VCMJDEBUBXPVMEOPUCFIBOEMFEJOUIFTBNFWFSUJDBMTMJDFBTUIFQSJWBUFEBUB $234JTBNPSFBQQSPQSJBUFDIPJDFGPSQVCMJDEBUB BOEUIFSF  JUDBONBLFTFOTFUPIBWFEJ ff FSFOUWFSUJDBMTMJDFTGPSUIFDPNNBOEBOERVFSZQBSUT #PVOEFE$POUFYU 5PQ-FWFM"SDIJUFDUVSF

Slide 28

Slide 28 text

3%#ͰʮΠϕϯτʯͱʮϦιʔεʯΛ۠ผ͠ͳ͕ΒɺςʔϒϧΛઃܭ͢Δ Πϕϯτͷ֓೦తԸܙΛड͚ͭͭ΋ɺ݁Ռ੔߹ͷΫΤϦ͕ඞਢͰͳ͘ͳΔ ඞཁͳUBCMFKPJO͕૿͑ͨΓɺΠϯϐʔμϯεϛεϚον͕ܹ͘͠ͳΓ΍͍͢՝୊͕͋Δ *NNVUBCMF%BUB.PEFM

Slide 29

Slide 29 text

package subscription // ू໿ϧʔτ type Subscription struct { ID uuid.UUID Status Status } // ू໿ϧʔτͷίϚϯυϝιου͕ɺෆม৚݅Λҡ࣋͠ͳ͕ΒΠϕϯτΛ࡞੒͢Δ func (s Subscription) Deactivate(deactivateAt time.Time) (Deactivated, error) { // write some invariants here if s.Status == Deactivated { return Deactivated{}, fmt.Errorf("subscription is already deactivated: %w", errors.ErrPreconditionFailed) } return Deactivated{SubscriptionID: s.ID, DeactivateAt: deactivateAt}, nil } // Πϕϯτ type Deactivated struct { SubscriptionID uuid.UUID DeactivatedAt time.Time } func (SubscriptionDeactivated) IsSubscriptionEvent() {} type Event interface { IsSubscriptionEvent() } // ϦϙδτϦ: Πϕϯτͷอଘͱू໿ͷϩʔυ͕Մೳ type Repository interface { Store(context.Context, Event) error Load(context.Context, uuid.UUID) (Subscription, error) } *NQMFNFOUJOH"HHSFHBUF

Slide 30

Slide 30 text

package command // ίϚϯυ: ૢ࡞ͷ໊લͱͦΕ࣮ߦ͢ΔͨΊʹඞཁͳೖྗσʔλΛ࣋ͭ type DeactivateSubscriptionCommand struct { SubscriptionID uuid.UUID } // ίϚϯυϓϩηοαʔ: ू໿ʹίϚϯυॲཧΛҕৡ͢Δ func (p DeactivateSubscriptionCommandProcessor) Exec(ctx context.Context, command DeactivateSubscriptionCommand) (subscription.Deactivated, error) { aSubscription, err := p.SubscriptionRepo.Load(ctx, command.SubscriptionID) if err != nil { return subscription.Deactivated{}, fmt.Errorf("subscription.Repository.Load: %w", err) } event, err := aSubscription.Deactivate(time.Now()) if err != nil { return subscription.Deactivated{}, fmt.Errorf("subscription.Subscription.Deactivate: %w", err) } if err := p.SubscriptionRepo.Store(ctx, event); err != nil { return subscription.Deactivated{}, fmt.Errorf("subscription.Repository.Store: %w", err) } if err := p.EventPublisher.Publish(ctx, event); err != nil { return subscription.Deactivated{}, fmt.Errorf("EventPublisher.Publish: %w", err) } return event, nil } *NQMFNFOUJOH$PNNBOE

Slide 31

Slide 31 text

package redis type SubscriptionDeactivatedEventHandler struct { AsynqClient *asynq.Client } func (h SubscriptionDeactivatedEventHandler) HandleSubscriptionDeactivated(ctx context.Context, event subscription.Deactivated) error { // Ϗδωεϧʔϧ͸੾Γग़͓ͯ͘͠ if policy.CanDeactivateMembershipcard(event) { payload, err := json.Marshal(task.DeactivateMembershipcardPayload{SubscriptionID: event.SubscriptionID}) if err != nil { return fmt.Errorf("marshal payload: %w", err) } // Ωϡʔʹ٧ΊͯผϓϩηεʹॲཧΛ೚ͤΔ _, err = h.AsynqClient.EnqueueContext(ctx, asynq.NewTask(task.DeactivateMembershipcard, payload)) if err != nil { return fmt.Errorf("enqueue process deactivate membershipcard task: %w", err) } } return nil } ˞࣮ߦͰ͖ͳ͍৔߹ͷϦτϥΠՄೳੑɺෳ਺ճ࣮ߦ͞Εͨ৔߹ͷႈ౳ੑɺଞͷΠϕϯτͱͷॱংੑɺΛߟྀ͓ͯ͘͠ඞཁ͋Γ *NQMFNFOUJOH1PMJDZ

Slide 32

Slide 32 text

package query // ΫΤϦαʔϏε type SubscriptionService interface { QueryPage(ctx context.Context, filter SubscriptionFilter, sorter SubscriptionSorter, limit int, cursor *string) (Page[Subscription], error) QueryByIDs(context.Context, []string) ([]Subscription, error) QueryByID(context.Context, string) (Subscription, error) } // ΫΤϦϞσϧ type Subscription struct { ID string CustomerID string ProductID string NextRenewAt time.Time LastRenewedAt time.Time } // ϑΟϧλʔ&ιʔτ type SubscriptionFilter struct { CustomerID string } type SubscriptionSorter struct { Key SubscriptionSortKey Direction SortDirection } 2VFSZ4FSWJDF.PEFM

Slide 33

Slide 33 text

ϞσϧΛோΊͯΈΔͱɺ$234Ͱ࣮૷͢ΔͱΑͦ͞͏ͳՕॴͱɺͦ͏Ͱ΋ͳ͍Օॴ͕͋Δ ɾ͕࣌ؒ࣠ؔ܎͠ͳ͍ ɾຊདྷతʹޠኮ͕$36%ɺίϚϯυɾΠϕϯτʹແཧʹ౰ͯ͸Ί͍ͯΔ ɾ๛෋ͳϙϦγʔ͕͋Δ ɾ࣌ؒ࣠ͰυϝΠϯ͕มԽ͍ͯ͘͠ ɾ$36%Ͱ͸ͳ͍ޠኮͰ੒Γཱ͍ͬͯΔ #VU$36%ʜʁ

Slide 34

Slide 34 text

$36%ΛϢϏΩλεݴޠʹ͍ͯ͠Δ෦෼ͷ$234࣮૷͸ɺ΍͸Γແବ ͱ͸͍͑ผͷΞʔΩςΫνϟύλʔϯͱڞଘͤ͞Δͷ΋ɺҙࢥܾఆͷස౓΍ֶशίετΛ૿΍ͯ͠͠·͏ ίϚϯυʹҙਤ͕ͳ͘ɺू໿Ͱڧ੍͢Δෆม৚͕݅ͳ͘ɺΠϕϯτ͸࣮࣭ू໿ͷεφοϓγϣοτʹʜ package product func (p Product) Update(name Name, description Description, updateAt time.Time) (ProductUpdated, error) { return ProductUpdated{ ProductID: p.ID, Name: name.value, Description: description.value, UpdatedAt: updateAt, }, nil } #VU$36%ʜʁ

Slide 35

Slide 35 text

7BVHIO7FSOPO JNQMFNFOUJOHEPNBJOESJWFOEFTJHO ͋·ΓΞʔΩςΫνϟʹؾΛͱΒΕ͗ͯ͢͠·͏ͱɺ %%%Λ࢖ͬͯ஫ҙਂ͘ϞσϧΛ࡞Δ͜ͱ͕ ͓Ζ͔ͦʹͳͬͯ͠·͍͕ͪͩɻ தུ  υϝΠϯϞσϧͷ΄͏͕ࣄۀՁ஋Λଟ͘ੜΈग़͢͠ɺ ͦͷӨڹ΋௕ଓ͖͢Δɻ %FTJHO'PS8IPNʁ ಺෦඼࣭Λॏཁࢹͭͭ͠ɺ ׬ᘳओٛʹؕΒͳ͍Α͏ʹ͢Δ υϝΠϯͱϢʔβʔͷՁ஋ʹ ͳΔͷ͔ʁͱ͍͏໰͍ʹཱͪ໭Δ

Slide 36

Slide 36 text

εΩϧɺܦݧɺࢥߟͷҟͳΔਓʑͱίϥϘϨʔγϣϯͯ͠ɺٕज़ͱ૑଄ྗͰυϝΠϯΛਐԽ͍ͤͯ͘͞ ۀ຿Λͦͷ··ιϑτ΢ΣΞʹ͢Δ͚ͩͰ͸ɺςΫϊϩδʔʹΑΔޮ཰ԽҎ্ͷΠϯύΫτ͸ى͖ͳ͍ʜ ࣄۀͱϓϩμΫτ͕੒ޭͨ͠Βɺ$234 &4͕ޮՌతʹ࢖͑ΔྖҬ͸΋ͬͱ૿͍͑ͯ͘͸ͣʂ $PODMVTJPO ·ͣ͸υϝΠϯʹ޲͖߹ͬͯɺͦΕ͔Β$234Ͱ࣮૷͢Δ

Slide 37

Slide 37 text

8FBSFIJSJOH IUUQTXXXXBOUFEMZDPNDPNQBOJFTDPNQBOZ@ 5IBOLZPVGPSMJTUFOJOH %.!NFNFUJDT ✉ LBCF!EJHJUUMFDPKQ