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

クラシコムとLaravelとDDD

Takeru Hirose
September 13, 2018

 クラシコムとLaravelとDDD

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 Ͳ͏͢Ε͹ྑ͍ͷͩΖ͏ʁ