Slide 1

Slide 1 text

ኍ੉݈ʢגࣜձࣾΫϥγίϜʣ -BSBWFM.FFUVQ5PLZP7PM ΫϥγίϜͱ-BSBWFMͱ%%%

Slide 2

Slide 2 text

೥ɺѪ஌ݝੜ·Εɻ೥݄ɺגࣜձࣾΫϥγίϜʹೖࣾɻ લ৬·Ͱ͸3VCZPO3BJMTͰͷΞϓϦέʔγϣϯ։ൃɺσβΠϯ૊৫ ͷ্ཱͪ͛ͳͲʹܞΘΔɻݱࡏ͸-BSBWFMͰͷΞϓϦέʔγϣϯ։ൃ ͷ΄͔ɺσβΠφʔ࠾༻ʹऔΓ૊Ήɻ ኍ੉݈5BLFSV)JSPTF!UBLFSV

Slide 3

Slide 3 text

w &$ϝσΟΞͷΑ͏ͳαΠτ w ݄ؒ17໿ ສ w ݄ؒ66໿ສ w ࣾ಺Ͱ։ൃɾӡ༻ ΫϥγίϜʮ๺Ԥɺ฻Β͠ͷಓ۩ళʯΛӡӦ IPLVPILVSBTIJDPN

Slide 4

Slide 4 text

-BSBWFM%%%ʢΫϥγίϜͷ৔߹ʣ

Slide 5

Slide 5 text

3BJMT͔Β-BSBWFM΁ͷॻ͖׵͑ϓϩδΣΫτ ঎඼ϖʔδ Χʔτʢܾࡁʣ -BSBWFM%%%Λ࠾༻

Slide 6

Slide 6 text

ۀ຿஌ࣝΛίʔυͰදݱ ʢ-BSBWFMʹͰ͖Δ͚ͩґଘ͠ͳ͍ʣ -BZFSFE"SDIJUFDUVSF 1SFTFOUBUJPO-BZFS *OGSBTUSVDUVSF-BZFS "QQMJDBUJPO-BZFS %PNBJO-BZFS -BSBWFMͷػೳΛ࠷େݶʹ׆༻

Slide 7

Slide 7 text

w ϢϏΩλεݴޠΫϥεʢܕʣʢ&OUJUZ 7BMVF0CKFDU FUDʣ w ྫʣ"QQa%PNBJOa.PEFMTa6TFSa&OUJUZ w ֤Ϋϥε͸1MBJO0ME1)10CKFDU 1010 w &OUJUZͰ͋ͬͯ΋&MPRVFOUa.PEFMΛܧঝ͠ͳ͍ʢ&MPRVFOUͱ͸ผ෺ʣ w ίϯετϥΫλʹΑͬͯෆม৚݅ΛνΣοΫ͢Δ w ࢓༷ʹ൓͍ͯ͠Ε͹ྫ֎ʢΠϯελϯεΛ࡞Δ͜ͱ͕Ͱ͖ͳ͍ʣ ۀ຿஌ࣝʢυϝΠϯϩδοΫʣΛίʔυͰදݱ

Slide 8

Slide 8 text

ྫʣ߹ܭֹۚͷܭࢉ ঎඼୯Ձ ஫จ਺ྔ খܭ ߹ܭ ഑ૹྉ

Slide 9

Slide 9 text

ྫʣ߹ܭֹۚͷܭࢉ ঎඼୯Ձ Product\UnitPrice ஫จ਺ྔ Order\Quantity খܭ Order\SubTotal ߹ܭ Order\Total ഑ૹྉ Shipping\Fee

Slide 10

Slide 10 text

declare(strict_types=1); final class Product\UnitPrice { public function __construct(int $value) { if ($value < 0) { throw new \InvalidArgumentException(); } $this->value = $value; } } ྫʣ঎඼୯Ձ WBMVFͷʮ঎඼୯Ձʯ͸࡞Εͳ͍ WBMVF͸ඞͣJOU

Slide 11

Slide 11 text

declare(strict_types=1); final class Order\Quantity { public function __construct(int $value) { if ($value < 1) { throw new \InvalidArgumentException(); } $this->value = $value; } } ྫʣ஫จ਺ྔ WBMVFͷʮ஫จ਺ྔʯ͸࡞Εͳ͍ WBMVF͸ඞͣJOU

Slide 12

Slide 12 text

declare(strict_types=1); final class Order\SubTotal { public function __construct( Product\UnitPrice $unitPrice, Order\Quantity $quantity ) { $this->value = $unitPrice->value() * $quantity->value(); } } ྫʣখܭ঎඼୯Ձ஫จ਺ྔ ʮখܭʯ͸ඞͣʮ঎඼୯Ձʯͱʮ஫จ਺ྔʯ͔Β࡞ΒΕΔ

Slide 13

Slide 13 text

declare(strict_types=1); final class Shipping\Method { public function calculateFee(Order\SubTotal $subTotal): Shipping\Fee { if ($subTotal->value() >= self::IS_FREE) { return new Shipping\Fee(0); } return new Shipping\Fee(self::REGULAR_FEE); } } ྫʣখܭ͕ҰఆֹۚҎ্ͷ৔߹͸഑ૹྉ͕ແྉ ඞͣʮখܭʯΛ༻͍ͯܭࢉ͞ΕΔ ඞͣʮ഑ૹྉʯΛฦ͢

Slide 14

Slide 14 text

declare(strict_types=1); final class Order\Total { public function __construct( Shipping\Method $shippingMethod, Order\SubTotal $subTotal ) { $shippingFee = $shippingMethod->calculateFee($subTotal); $this->value = $subTotal->value() + $shippingFee->value(); } } ྫʣ߹ܭখܭখܭΛجʹܭࢉ͞Εͨ഑ૹྉ ࢓༷Ҏ֎ͷํ๏Ͱʮ߹ܭʯΛ࡞Δ͜ͱ͕Ͱ͖ͳ͍

Slide 15

Slide 15 text

w ۀ຿஌ࣝΛݴޠ࢓༷ʹΑͬͯදݱͰ͖Δʢڧ੍Ͱ͖Δʣ w Ҿ਺ɾฦΓ஋ͷܕࢦఆ͕ͦͷ··ͦͷ֓೦ͷ࢓༷ɾؔ܎ੑΛදݱ w ࢓༷ʹ൓͍ͯ͠Ε͹࣮ߦͰ͖ͳ͍˰όάͷ௿ݮɾૣظൃݟ w ࢓༷ʢϩδοΫʣ͕Ϋϥεʹ಺แ͞Ε͍ͯΔͷͰࢄҳ͠ͳ͍ w ফඅ੫ͱ͔ʜʢ੫ࠐՁ֨਺ྔPS੫ൈՁ֨਺ྔ੫཰ʣ w ࢓༷ʹ൓ͨ͠Πϯελϯε͕ଘࡏ͠ಘͳ͍ͷͰඞཁͳςετ΋ݮΔ ϢϏΩλεݴޠΫϥεʢܕʣ

Slide 16

Slide 16 text

Ҿ਺ɾฦΓ஋ͷؒҧ͍˰5ZQF&SSPS ݴޠ࢓༷ʹΑͬͯදݱͰ͖Δͱ͍͏͜ͱ ࢓༷ʹ൓͢Δ৔߹˰-PHJD&YDFQUJPO ➔ྫ֎͕ى͖ͳ͍Α͏ʹ࣮૷͢Ε͹͍͍ͩͨେৎ෉ l͜ͷྨͷྫ֎͕ग़ͨ৔߹͸ɺࣗ෼͕ॻ͍ ͨίʔυΛमਖ਼͢΂͖Ͱ͢ɻz

Slide 17

Slide 17 text

-BSBWFMͱ%%%ͷ౷߹

Slide 18

Slide 18 text

%PNBJO-BZFS⾩*OGSBTUSVDUVSF-BZFS 1SFTFOUBUJPO-BZFS *OGSBTUSVDUVSF-BZFS "QQMJDBUJPO-BZFS %PNBJO-BZFS

Slide 19

Slide 19 text

w 3FQPTJUPSZ1BUUFSO w &OUJUZࣗ਎͸ӬଓԽʹؔ͢ΔϝιουΛ࣋ͨͳ͍ w 3FQPTJUPSZ͔Βऔಘˠมߋˠ3FQPTJUPSZʹ౉͢͜ͱͰอଘ w 3FQPTJUPSZ಺Ͱ&MPRVFOU⾩&OUJUZΛ૬ޓม׵ w 3FQPTJUPSZ͕֎෦ͱ΍ΓͱΓ͢Δ஋͸%PNBJO-BZFSͷΫϥεʢܕʣ w &MPRVFOU͸03.ͩͱׂΓ੾ΔʢରͰରԠ͍ͯ͠Δͱ͸ݶΒͳ͍ʣ w 3FQPTJUPSZ&MPRVFOUʹͰ͖Δ͚ͩۀ຿஌ࣝΛ࣋ͨͤͳ͍ &OUJUZͷӬଓԽ

Slide 20

Slide 20 text

declare(strict_types=1); final class UserRepository implements User\Repository { public function find(User\Id $id): User\Entity { $record = UserEloquent::find($id->value()); $entity = ...; return $entity; } public function store(User\Entity $entity): void { $record = ...; $record->save(); } } ྫʣ6TFS3FQPTJUPSZ JOUFSGBDF͸%PNBJO-BZFSʹ഑ஔˠ4FSWJDF1SPWJEFSʹొ࿥ &MPRVFOUˠ&OUJUZʹม׵ &OUJUZˠ&MPRVFOUʹม׵

Slide 21

Slide 21 text

"QQMJDBUJPO-BZFS⾩%PNBJO-BZFS 1SFTFOUBUJPO-BZFS *OGSBTUSVDUVSF-BZFS "QQMJDBUJPO-BZFS %PNBJO-BZFS

Slide 22

Slide 22 text

w $POUSPMMFSͷ໾ׂ͸6*ͱ%PNBJO-BZFSͷؒΛऔΓ࣋ͭ͜ͱ w Ϣʔβ͔ΒͷೖྗΛ%PNBJO-BZFSͷ֓೦ʹม׵͢Δ w %PNBJO-BZFSͷ֓೦ΛϢʔβ΁ͷग़ྗʹม׵͢Δ w 7BMJEBUPSͷ໾ׂ͸ʮྫ֎Λൃੜͤ͞ͳ͍͜ͱʯ w ෆਖ਼ͳೖྗΛϢʔβʹ෼͔Γ΍͘͢ϑΟʔυόοΫ͢Δ͜ͱʹूத͢Δ ʢσʔλͷ੔߹ੑ͸%PNBJO-BZFSҎԼʹΑͬͯ୲อ͞Ε͍ͯΔʣ w %PNBJO-BZFSΛʮ࢖͏ଆʯ͕ࣄલ৚݅ɾෆม৚݅Λຬͨٛ͢຿Λෛ͏
 ʢܖ໿ʹΑΔઃܭʣ $POUSPMMFS7BMJEBUPS

Slide 23

Slide 23 text

declare(strict_types=1); class UsersController extends Controller { public function show(int $id) { $user = app(User\Repository::class)->find(new User\Id($id)); // [...] } public function store(StoreRequest $request) { $data = $request->validate(); $user = ...; app(User\Repository::class)->store($user); } } ྫʣ6TFST$POUSPMMFS "QQMJDBUJPO-BZFS͸%PNBJO-BZFSʹ഑ஔ͞ΕͨJOUFSGBDFʹґଘ͢Δ 7BMJEBUPSΛ௨աͨ͠஋ʹΑͬͯ&OUJUZΛੜ੒

Slide 24

Slide 24 text

w -BSBWFMͷ͍͍ͨͯͷػೳ͸*OUFSGBDFΛ࣮૷͍ͯ͠Ε͹࢖͑Δ w Ϣʔβʔೝূʢ"VUIFOUJDBUJPO"VUIPSJ[BUJPOʣ͸6TFS.PEFM͕&MPRVFOU Ͱͳͯ͘΋࢖͑Δ w -BSBWFMʹ༻ҙ͞Ε͍ͯΔ֦ுͷ࢓૊ΈΛ࠷େݶʹ׆༻͢Δ w #MBEFͷ%JSFDUJWFΛ֦ு͢Ε͹WJFXʹ͓͍ͯ%PNBJO-BZFSͷΫϥεΛࣗ વʹ࢖͑Δ ͦͷଞ

Slide 25

Slide 25 text

΍ͬͯΈͯͲ͏͔ͩͬͨ

Slide 26

Slide 26 text

w ۀ຿஌ࣝʹର͢Δཧղ͕ਂ·Δʢ෼͔Βͳ͍ͱ࡞Εͳ͍ʣ w ࣗ෼͕ϓϩδΣΫτʹೖͬͨͷ͸ೖࣾͯ͠ϲ݄ޙ͘Β͍ w Ҏલ͔Β͍ΔΤϯδχΞͱҰॹʹϞσϦϯάˠϞϒϓϩάϥϛϯά w ίʔυͰදݱ͠Α͏ͱ͢Δ͜ͱͰ࢓༷͕໌շʹͳΔ w ͢΂ͯͷ֓೦Λ࿦ཧతʹهड़͢ΔͨΊᐆດͳ࢓༷͕ଘࡏ͠ಘͳ͍ w ࿦ཧతʹໃ६ͨ͠࢓༷͕ൃݟ͞Εͨ͜ͱ΋ w ίʔυΛಡΊ͹࢓༷͕෼͔Δˠߏஙޙ΋ۀ຿஌ࣝͷڞ༗͕༰қ ʮֶͼʯ͕൒୺ͳ͍

Slide 27

Slide 27 text

ʮֶͼʯ͕൒୺ͳ͍ Ϟϒϓϩάϥϛϯά ϞσϦϯά

Slide 28

Slide 28 text

w ۀ຿஌ࣝʢ࠷΋େࣄͰෳࡶͳ෦෼ʣʹؔ͢Δςετ͕γϯϓϧʹͳΔ w ୯७ͳςετͷੵΈॏͶʹΑͬͯ࢓༷͕कΒΕ͍ͯΔ͜ͱΛ୲อͰ͖Δ w པΓʹͳΔίʔυΧόϨοδɾ੩తղੳʢQIQTUBOʣ w ʮ࠷ѱͷࣄଶʯΛট͘ϦεΫΛ௿ݮͰ͖Δ w ݴޠ࢓༷ͷ੍໿ʹΑΓۀ຿஌͔ࣝΒҳ୤ͨ͠هड़͸࣮ߦͰ͖ͳ͍ w ྫ֎͕ى͖ͳ͍Α͏ʹ࣮૷͢Ε͹͍͍ͩͨେৎ෉ʢ࠶ܝʣ ҆৺ײ͕൒୺ͳ͍

Slide 29

Slide 29 text

ྫʣখܭΛςετ͢Δ৔߹ ঎඼୯Ձ Product\UnitPrice ஫จ਺ྔ Order\Quantity খܭ Order\SubTotal

Slide 30

Slide 30 text

class ProductUnitPriceTest extends TestCase { public function testConstruct(): void { $expectedValue = $this->faker()->numberBetween(0); $unitPrice = new Product\UnitPrice($expectedValue); $this->assertEquals($expectedValue, $unitPrice->value()); } public function testConstructFail(): void { $this->expectException(\InvalidArgumentException::class); $invalidValue = $this->faker()->numberBetween(-2147483647, -1); new Product\UnitPrice($invalidValue); } } ྫʣ঎඼୯Ձͷςετ ਖ਼ৗܥʢWBMVFʣ ҟৗܥʢWBMVFʣ

Slide 31

Slide 31 text

class OrderQuantityTest extends TestCase { public function testConstruct(): void { $expectedValue = $this->faker()->numberBetween(1); $quantity = new Order\Quantity($expectedValue); $this->assertEquals($expectedValue, $quantity->value()); } public function testConstructFail(): void { $this->expectException(\InvalidArgumentException::class); $invalidValue = $this->faker()->numberBetween(-2147483647, 0); new Order\Quantity($invalidValue); } } ྫʣ஫จ਺ྔͷςετ ਖ਼ৗܥʢWBMVFʣ ҟৗܥʢWBMVFʣ

Slide 32

Slide 32 text

class OrderSubTotalTest extends TestCase { public function testConstruct(): void { $unitPrice = new Product\UnitPrice($this->faker()->numberBetween(0)); $quantity = new Order\Quantity($this->faker()->numberBetween(1)); $expectedValue = $unitPrice->value() * $quantity->value(); $subTotal = new Order\SubTotal($unitPrice, $quantity); $this->assertEquals($expectedValue, $subTotal->value()); } } ྫʣখܭͷςετ Ҿ਺ͱͳΔΦϒδΣΫτͷҟৗܥ͸ςετࡁΈ Ҿ਺ͷܕ͸ݴޠ࢓༷ʹΑͬͯอূ͞Ε͍ͯΔˠͨͩͷֻ͚ࢉͷςετ

Slide 33

Slide 33 text

w ΄ͱΜͲͷ෼ذ͕୯७ w ˠ༰қʹ໢ཏͰ͖Δ w ˠ໢ཏͰ͖͍ͯΕ͹҆৺ w !DPWFSTΛͪΌΜͱॻ͘ • forceCoversAnnotation="true" པΓʹͳΔίʔυΧόϨοδ

Slide 34

Slide 34 text

҆৺ײ͕൒୺ͳ͍ ੩తղੳʢQIQTUBOʣ ΧόϨοδʢ$PWFSBMMTʣ

Slide 35

Slide 35 text

w ϞσϦϯά೉͍͠ w Ϟσϧͷڥքͱ%#ͷτϥϯβΫγϣϯ΍ύϑΥʔϚϯεͱͷ݉Ͷ߹͍ w Ϟσϧͷ੔߹ੑͱ6*ͷॊೈੑͱͷ݉Ͷ߹͍ w ྫʣ഑ૹઌ͕ܾఆ͞Ε͍ͯͳ͍ͷʹ഑ૹྉΛද͍ࣔͨ͠ w ͦ΋ͦ΋-BSBWFMʢ1)1ʣͰ΍Δ΂͖ͩͬͨͷ͔ʁ w 1)1Ͱ΋ܕΛѻ͏ݴޠͱͯ͠͸·ͩ·ͩඇྗʢδΣωϦοΫͱ͔ʣ w ΍ͬͺΓ&MPRVFOUΛૉ௚ʹ࢖ͬͨ΄͏͕-BSBWFM͸׆͖Δ w -BSBWFMͷར఺ͷҰͭͰ͋Δ։ൃ଎౓͸Ͳ͏ͯ͠΋٘ਜ਼ʹͳΔ ൓ল఺ʢ΍ͬͯΈͯ෼͔ͬͨ͜ͱʣ

Slide 36

Slide 36 text

w %%%͕ઃܭख๏ͱͯ͠༗༻ͳͷ͸͔͕֬ͩɺͲ͜·Ͱίʔυʹམͱ͠ ࠐΉ͔͸બ୒ͷ༨஍ʢ෯ʣ͕͋Δͱࢥ͏ w Ϣʔβʔʹ͍ۙ෦෼͸ૉૣ͘։ൃɾ൓෮͍ͨ͠ʢ-BSBWFMΒ͘͠࡞Γ͍ͨʣ w Ϗδωε্ͷཧ༝ʹΑΓ࢓༷ͱ6*͕ໃ६͢Δ͜ͱ͸Α͋͘Δ͜ͱ w %%%ͰखʹೖΔݎ࿚ੑɾอकੑ͸٘ਜ਼ʹͨ͘͠ͳ͍ w 4P& 4ZTUFNPG&OHBHFNFOU 4P3 4ZTUFNPG3FDPSE ͱ͍͏੾ΓޱͰ ΞϓϦέʔγϣϯΛ෼ׂ͢Δͷ͸ΞϦ͔΋͠Εͳ͍ w 4P3తͳ෦෼͕ಷॏʹͳͬͯ΋͍͚ͳ͍ˠ.JDSPTFSWJDFT"SDIJUFDUVSF Ͳ͏͢Ε͹ྑ͍ͷͩΖ͏ʁ

Slide 37

Slide 37 text

4P&4P3ͱ͍͏੾ΓޱͰΞϓϦέʔγϣϯΛ෼ׂʁ "QQMJDBUJPO 4P& %PNBJO" 4P3 *OGSBTUSVDUVSF" %#֎෦"1* ૉૣ͍։ൃɾ൓෮ ݎ࿚ੑɾอकੑʢେ͖͘ͳΓ͗͢ͳ͍Α͏ʹ෼ׂʣ ಈతܕ෇͚ݴޠʁ ੩తܕ෇͚ݴޠʁ %PNBJO# 4P3

Slide 38

Slide 38 text

·ͱΊ

Slide 39

Slide 39 text

w %%%ΛऔΓೖΕΔԸܙ͸େ͖͍ʢֶͼͱ҆৺ײʣ w ֦ுʹରͯ͠։͔Ε͍ͯΔͷ͸-BSBWFMͷྑ͍ͱ͜Ζ w ΞϓϦέʔγϣϯͷੑ࣭΍ߏ੒ɺݴޠɾ'8ͷಛੑΛؑΈͯɺऔΓೖ Εํ͸΋ͬͱߟ͍͖͍͑ͯͨ ·ͱΊ

Slide 40

Slide 40 text

ΫϥγίϜͰ͸ΤϯδχΞɾσβΠφʔΛืू͍ͯ͠·͢ IUUQTXXXXBOUFEMZDPNDPNQBOJFTLVSBTIJDPN

Slide 41

Slide 41 text

͝ਗ਼ௌ͋Γ͕ͱ͏͍͟͝·ͨ͠