Upgrade to Pro — share decks privately, control downloads, hide ads and more …

クラシコムとLaravelとDDD

Avatar for Takeru Hirose Takeru Hirose
September 13, 2018

 クラシコムとLaravelとDDD

Avatar for Takeru Hirose

Takeru Hirose

September 13, 2018
Tweet

More Decks by Takeru Hirose

Other Decks in Programming

Transcript

  1. w &$ ϝσΟΞͷΑ͏ͳαΠτ w ݄ؒ17໿ ສ w ݄ؒ66໿ສ w ࣾ಺Ͱ։ൃɾӡ༻

    ΫϥγίϜʮ๺Ԥɺ฻Β͠ͷಓ۩ళʯΛӡӦ IPLVPILVSBTIJDPN
  2. w ϢϏΩλεݴޠΫϥεʢܕʣʢ&OUJUZ 7BMVF0CKFDU FUDʣ w ྫʣ"QQa%PNBJOa.PEFMTa6TFSa&OUJUZ w ֤Ϋϥε͸1MBJO0ME1)10CKFDU 1010 

    w &OUJUZͰ͋ͬͯ΋&MPRVFOUa.PEFMΛܧঝ͠ͳ͍ʢ&MPRVFOUͱ͸ผ෺ʣ w ίϯετϥΫλʹΑͬͯෆม৚݅ΛνΣοΫ͢Δ w ࢓༷ʹ൓͍ͯ͠Ε͹ྫ֎ʢΠϯελϯεΛ࡞Δ͜ͱ͕Ͱ͖ͳ͍ʣ ۀ຿஌ࣝʢυϝΠϯϩδοΫʣΛίʔυͰදݱ
  3. 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
  4. 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
  5. declare(strict_types=1); final class Order\SubTotal { public function __construct( Product\UnitPrice $unitPrice,

    Order\Quantity $quantity ) { $this->value = $unitPrice->value() * $quantity->value(); } } ྫʣখܭ঎඼୯Ձ ஫จ਺ྔ ʮখܭʯ͸ඞͣʮ঎඼୯Ձʯͱʮ஫จ਺ྔʯ͔Β࡞ΒΕΔ
  6. 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); } } ྫʣখܭ͕ҰఆֹۚҎ্ͷ৔߹͸഑ૹྉ͕ແྉ ඞͣʮখܭʯΛ༻͍ͯܭࢉ͞ΕΔ ඞͣʮ഑ૹྉʯΛฦ͢
  7. 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(); } } ྫʣ߹ܭখܭ খܭΛجʹܭࢉ͞Εͨ഑ૹྉ ࢓༷Ҏ֎ͷํ๏Ͱʮ߹ܭʯΛ࡞Δ͜ͱ͕Ͱ͖ͳ͍
  8. 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ʹม׵
  9. 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Λੜ੒
  10. 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ʣ
  11. 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ʣ
  12. 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()); } } ྫʣখܭͷςετ Ҿ਺ͱͳΔΦϒδΣΫτͷҟৗܥ͸ςετࡁΈ Ҿ਺ͷܕ͸ݴޠ࢓༷ʹΑͬͯอূ͞Ε͍ͯΔˠͨͩͷֻ͚ࢉͷςετ
  13. w ϞσϦϯά೉͍͠ w Ϟσϧͷڥքͱ%#ͷτϥϯβΫγϣϯ΍ύϑΥʔϚϯεͱͷ݉Ͷ߹͍ w Ϟσϧͷ੔߹ੑͱ6*ͷॊೈੑͱͷ݉Ͷ߹͍ w ྫʣ഑ૹઌ͕ܾఆ͞Ε͍ͯͳ͍ͷʹ഑ૹྉΛද͍ࣔͨ͠ w ͦ΋ͦ΋-BSBWFMʢ1)1ʣͰ΍Δ΂͖ͩͬͨͷ͔ʁ

    w 1)1Ͱ΋ܕΛѻ͏ݴޠͱͯ͠͸·ͩ·ͩඇྗʢδΣωϦοΫͱ͔ʣ w ΍ͬͺΓ&MPRVFOUΛૉ௚ʹ࢖ͬͨ΄͏͕-BSBWFM͸׆͖Δ w -BSBWFMͷར఺ͷҰͭͰ͋Δ։ൃ଎౓͸Ͳ͏ͯ͠΋٘ਜ਼ʹͳΔ ൓ল఺ʢ΍ͬͯΈͯ෼͔ͬͨ͜ͱʣ
  14. w %%%͕ઃܭख๏ͱͯ͠༗༻ͳͷ͸͔͕֬ͩɺͲ͜·Ͱίʔυʹམͱ͠ ࠐΉ͔͸બ୒ͷ༨஍ʢ෯ʣ͕͋Δͱࢥ͏ w Ϣʔβʔʹ͍ۙ෦෼͸ૉૣ͘։ൃɾ൓෮͍ͨ͠ʢ-BSBWFMΒ͘͠࡞Γ͍ͨʣ w Ϗδωε্ͷཧ༝ʹΑΓ࢓༷ͱ6*͕ໃ६͢Δ͜ͱ͸Α͋͘Δ͜ͱ w %%%ͰखʹೖΔݎ࿚ੑɾอकੑ͸٘ਜ਼ʹͨ͘͠ͳ͍ w

    4P& 4ZTUFNPG&OHBHFNFOU 4P3 4ZTUFNPG3FDPSE ͱ͍͏੾ΓޱͰ ΞϓϦέʔγϣϯΛ෼ׂ͢Δͷ͸ΞϦ͔΋͠Εͳ͍ w 4P3తͳ෦෼͕ಷॏʹͳͬͯ΋͍͚ͳ͍ˠ.JDSPTFSWJDFT"SDIJUFDUVSF Ͳ͏͢Ε͹ྑ͍ͷͩΖ͏ʁ