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

DDDパターンを活用した Laravelアプリケーション開発/ddd-with-laravel

shin1x1
October 29, 2016

DDDパターンを活用した Laravelアプリケーション開発/ddd-with-laravel

2016/10/29 Laravel Osaka 2016 http://php-jp.github.io/laravel-osaka-2016/

shin1x1

October 29, 2016
Tweet

More Decks by shin1x1

Other Decks in Technology

Transcript

  1. ɹ!shin1x1
    2016//29 LBSBWFM0TBLB
    %%%ύλʔϯΛ׆༻ͨ͠
    -BSBWFMΞϓϦέʔγϣϯ։ൃ

    View full-size slide

  2. ର৅γεςϜ

    Ϣʔεέʔε

    View full-size slide

  3. &$αΠτ
    ΧʔτʹೖΕΔ

    View full-size slide

  4. D
    .BTBTIJ4IJOCBSB!TIJOY
    %PNBJO%SJWFO%FTJHO
    wʮΤϦοΫɾΤϰΝϯεͷυϝΠϯۦಈઃܭʯ
    wυϝΠϯʹϑΥʔΧεͨ͠ઃܭɺ։ൃख๏
    wଟ͘ͷύλʔϯ͕঺հ͞Ε͍ͯΔ

    View full-size slide

  5. D
    .BTBTIJ4IJOCBSB!TIJOY
    ιϑτ΢ΣΞͷυϝΠϯ
    wγεςϜͷର৅ྖҬɺղܾ͢Δ໰୊ྖҬ
    wۀ຿γεςϜͰ͋Ε͹ɺ

    ର৅ͷϏδωε͕υϝΠϯ
    wιʔείʔυ؅ཧγεςϜͰ͋Ε͹ɺ

    ιϑτ΢ΣΞ։ൃ͕υϝΠϯ
    wຊηογϣϯͰ͸ɺ&$αΠτ͕υϝΠϯ

    View full-size slide

  6. ϢϏΩλεݴޠ

    View full-size slide

  7. ϢϏΩλεݴޠ
    D
    .BTBTIJ4IJOCBSB!TIJOY
    wυϝΠϯ༻ޠࣙॻ

    ঎඼ɺΧʔτɺΧʔτʹ঎඼ΛೖΕΔɺͳͲ
    wϓϩδΣΫτνʔϜ಺Ͱಉ͡ݴ༿Λར༻

    ։ൃऀ΋ϏδωεΤΩεύʔτ΋શһ
    wͦͷݴ༿ΛίʔυͰ΋ར༻

    ʢ໊લۭؒɺΫϥεɺϝιου౳ʣ

    View full-size slide

  8. ӳޠ ಺༰
    ঎඼ *UFN
    ൢച͢Δ঎඼ɻԼهͷଐੑΛ࣋ͭɻ

    ɾ঎඼*%
    ɾ঎඼໊

    ɾ঎඼Ձ֨

    ɾࡏݿ
    ঎඼*% *UFN*E
    ঎඼Λࣝผ͢Δίʔυ

    ঎඼͝ͱʹҰҙ
    ঎඼໊ *UFN/BNF ঎඼ͷ໊শ
    ঎඼Ձ֨ *UFN1SJDF
    ঎඼ͷൢചՁ֨

    Ҏ্ͷ੔਺
    ࡏݿ *UFN4UPDL
    ঎඼ͷࡏݿ਺
    Ҏ্ͷ੔਺

    View full-size slide

  9. ӳޠ ಺༰
    Χʔτ $BSU
    ߪೖ͢Δ঎඼ΛҰ࣌֨ೲ͢ΔೖΕ෺

    ΧʔτཁૉΛෳ਺࣋ͭ
    Χʔτཁૉ $BSU&MFNFOU
    Χʔτʹ֨ೲ͞Ε͍ͯΔཁૉ

    ঎඼໊ͱ঎඼ݸ਺Λଐੑʹ࣋ͭ
    ঎඼ݸ਺ *UFN$PVOU ঎඼ͷݸ਺ɻҎ্ͷ੔਺ɻ
    Χʔτʹ঎඼Λ
    ೖΕΔ
    "EE*UFN5P$BSU
    Χʔτʹ঎඼ΛೖΕΔ͜ͱɻ

    ঎඼ͱ঎඼ݸ਺Λ༩͑Δɻ

    ঎඼ݸ਺͸঎඼ࡏݿҎԼͰ͋Δඞཁ
    ͕͋Δɻ

    View full-size slide

  10. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΧʔτʹೖΕΔ"1*
    1045ϦΫΤετ͔Β঎඼*%ͱ঎඼ݸ਺Λऔಘ
    σʔλϕʔε͔Β঎඼*%Ͱ঎඼Λऔಘ
    Χʔτʹ঎඼ΛೖΕΔ
    ΧʔτΛηογϣϯʹอଘ
    ϨεϙϯεΛฦ͢

    View full-size slide

  11. ϨΠϠʔυ
    ΞʔΩςΫνϟ

    View full-size slide

  12. ϨΠϠʔυΞʔΩςΫνϟ
    D
    .BTBTIJ4IJOCBSB!TIJOY
    wγεςϜΛϨΠϠʢ૚ʣʹ෼ׂ
    wϨΠϠ͸ࣗ਎ͷ໾ׂΛ୲͏
    wϨΠϠؒͰڠௐͯ͠ɺॲཧΛߦ͏
    wϨΠϠؒͷྲྀΕ͸Ұํ௨ߦ

    View full-size slide

  13. %%%&SJD&WBOT
    D
    .BTBTIJ4IJOCBSB!TIJOY
    UI
    Application
    Infrastructure
    Domain

    View full-size slide

  14. D
    .BTBTIJ4IJOCBSB!TIJOY
    6*-BZFS
    wϢʔβʢ࿈ܞγεςϜؚΉʣͱγεςϜͷ઀఺
    wϢʔβ͸͜ͷϨΠϠΛ௨ͯ͡γεςϜʹ৮ΕΔ
    w)551 )5.- +40/ 45%*/ 45%065
    wϏϡʔɺ3FRVFTUɺ3FTQPOTF

    View full-size slide

  15. ඞཁ࠷௿ݶ͚ͩར༻
    ͪ͜Βʹ࣮૷

    View full-size slide

  16. ΞϓϦέʔγϣϯ
    υϝΠϯ
    ΠϯϑϥετϥΫνϟ

    View full-size slide

  17. ϨΠϠؒͷྲྀΕ
    D
    .BTBTIJ4IJOCBSB!TIJOY
    UI
    Application
    Infrastructure
    Domain

    View full-size slide

  18. υϝΠϯϨΠϠ

    View full-size slide

  19. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΧʔτʹೖΕΔ"1*
    1045ϦΫΤετ͔Β঎඼*%ͱ঎඼ݸ਺Λऔಘ
    σʔλϕʔε͔Β঎඼*%Ͱ঎඼Λऔಘ
    Χʔτʹ঎඼ΛೖΕΔ
    ΧʔτΛηογϣϯʹอଘ
    ϨεϙϯεΛฦ͢

    View full-size slide

  20. D
    .BTBTIJ4IJOCBSB!TIJOY
    υϝΠϯϨΠϠ
    wγεςϜͷυϝΠϯΛ࣮૷͢ΔϨΠϠ
    wυϝΠϯҎ֎ͷؔ৺ࣄ͸ؚΊͳ͍

    )551%#Ωϟογϡ౳
    w1010Ͱ࣮૷͠ɺϑϨʔϜϫʔΫ͔Β͸ಠཱ

    'BDBEF΍ϔϧύʔؔ਺΋࢖Θͳ͍
    wϞσϧɺαʔϏεɺΠϕϯτͳͲ

    View full-size slide

  21. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΤϯςΟςΟ
    wυϝΠϯϞσϧͷ࣮૷

    ঎඼ɺΧʔτ
    w&MPRVFOUΛܧঝ͠ͳ͍
    wಉҰੑ͸ࣝผࢠʢJEʣͰ൑ผ
    wϛϡʔλϒϧ

    View full-size slide

  22. D
    .BTBTIJ4IJOCBSB!TIJOY
    7BMVF0CKFDU
    wՁ֨΍೔෇ͳͲϓϦϛςΟϒͳ஋Λࣔ͢

    ঎඼*%ɺ঎඼Ձ֨ɺࡏݿ
    wಉҰੑ͸ଐੑͰ൑ผ
    w஋ʹର͢Δ੍໿΍ৼΔ෣͍ʢԋࢉʣΛ࣮૷
    wΠϛϡʔλϒϧ

    View full-size slide

  23. D
    .BTBTIJ4IJOCBSB!TIJOY
    ঎඼ΤϯςΟςΟ
    ঎඼ΤϯςΟςΟ͸ҎԼͷଐੑΛ࣋ͭ
    ಺༰ ৼΔ෣͍ʢԋࢉʣ
    ঎඼*%
    ঎඼ͷࣝผࢠ
    ঎඼͝ͱʹҰҙ
    ͳ͠
    ঎඼໊ ঎඼ͷ໊শ ͳ͠
    ঎඼Ձ֨
    ঎඼ͷՁ֨
    Ҏ্ͷ੔਺
    ɾ঎඼ݸ਺ͱͷֻ͚ࢉ
    ࡏݿ
    ঎඼ͷࡏݿ਺
    Ҏ্ͷ੔਺
    ɾࡏݿ͕ෆ଍͍ͯ͠Δ͔

    View full-size slide

  24. &MPRVFOU
    3FQPTJUPSZ
    class Item

    {

    /** @var int */

    private $id;


    /** @var string */

    private $name;


    /** @var int */

    private $price;


    /** @var int */

    private $stock;

    }

    int
    int
    int
    *UFNʢ঎඼ʣ

    View full-size slide

  25. &MPRVFOU
    3FQPTJUPSZ
    class Item

    {

    /** @var int */

    private $id;


    /** @var string */

    private $name;


    /** @var int */

    private $price;


    /** @var int */

    private $stock;

    }

    int
    int
    int
    *UFNʢ঎඼ʣ
    wυϝΠϯ͕൓ө͞Ε͍ͯͳ͍
    wUIJTTUPDLUIJTTUPDL

    ͋Γ͑ͳ͍ԋࢉ͕Ͱ͖Δ
    wUIJTQSJDF

    ૝ఆ֎ͷ࢖͍ํ͞ΕΔ

    View full-size slide

  26. &MPRVFOU
    3FQPTJUPSZ
    class Item

    {

    /** @var ItemId */

    private $id;


    /** @var string */

    private $name;


    /** @var ItemPrice */

    private $price;


    /** @var Stock */

    private $stock;

    }

    ItemId
    ItemPrice
    Stock
    ܕʢΫϥεʣͰදݱ

    View full-size slide

  27. &MPRVFOU
    3FQPTJUPSZ
    class ItemId

    {

    /** @var int */

    private $value;


    /**

    * @param int $value

    */

    public function __construct(int $value)

    {

    $this->value = $value;

    }


    public function value(): int

    {

    return $this->value;

    }

    }
    *UFN*E
    ৼΔ෣͍ʢԋࢉʣ͕ແ͍

    View full-size slide

  28. &MPRVFOU
    3FQPTJUPSZ
    class ItemPrice

    {

    /** @var int */

    private $value;



    public function __construct(int $value = 0)

    {

    if ($value < 0) {

    throw new PreconditionsException('value must be
    positive number:' . $value);

    }

    $this->value = $value;

    }

    //(snip)


    *UFN1SJDF
    ঎඼Ձ֨͸Ҏ্ͷ੔਺

    View full-size slide

  29. &MPRVFOU
    3FQPTJUPSZ

    public function multi(ItemCount $count): ItemSubtotal

    {

    return new ItemSubtotal($this->value * $count->value());

    }

    *UFN1SJDF
    ঎඼Ձ֨঎඼ݸ਺঎඼খܭ

    View full-size slide

  30. D
    .BTBTIJ4IJOCBSB!TIJOY
    7BMVF0CKFDUͷϙΠϯτ
    wϢϏΩλεݴޠΛίʔυͰදݱ

    ίʔυΛݟΕ͹࢓༷͕෼͔Δ
    wϝιουͰఆٛͨ͠ԋࢉ͔͠Ͱ͖ͳ͍

    ؒҧ͍ΛݮΒͤΔ
    w൚༻ܕͰ͸ͳ͘ಛԽܕͰ

    ʮ਺ࣈʯͰ͸ͳ͘ʮ঎඼Ձ֨ʯ
    wڽू౓্͕͕Γɺѻ͍΍͍͢ɻςετͷ༰қ

    View full-size slide

  31. &MPRVFOU
    3FQPTJUPSZ
    class Cart

    {

    /** @var CartElement[]|Collection */

    private $elements;


    public function addItem(Item $item, ItemCount $count)

    {

    if ($item->stock()->isInsufficient($count)) {

    throw new PreconditionsException('stock is insufficient');

    }


    $this->elements->push(new CartElement($item, $count));

    }

    $BSUΧʔτʹ঎඼ΛೖΕΔ
    ࡏݿ͕ෆ଍͍ͯ͠Δ͔ʁ

    View full-size slide

  32. &MPRVFOU
    3FQPTJUPSZ
    class Cart

    {

    /** @var CartElement[]|Collection */

    private $elements;


    public function addItem(Item $item, ItemCount $count)

    {

    if ($item->stock()->isInsufficient($count)) {

    throw new PreconditionsException('stock is insufficient');

    }


    $this->elements->push(new CartElement($item, $count));

    }

    $BSUΧʔτʹ঎඼ΛೖΕΔ
    ΧʔτཁૉΛ௥Ճ

    View full-size slide

  33. D
    .BTBTIJ4IJOCBSB!TIJOY
    υϝΠϯϨΠϠͷ࣮૷
    wϑϨʔϜϫʔΫ͔Βಠཱͯ͠1010Ͱ࣮૷
    w$PMMFDUJPOͳͲυϝΠϯΛදݱ͢ΔൣғͳΒPL
    w7BMVF0CKFDUͰυϝΠϯಛԽܕΛ࡞Γɺ

    ϢϏΩλεݴޠΛදݱ
    wυϝΠϯϨΠϠͰ͸70Λ࠷খཻ౓ʹ͢Δ

    70಺Ҏ֎Ͱ͸εΧϥʔܕ͸࢖Θͳ͍ʢཧ૝ʣ

    View full-size slide

  34. ΠϯϑϥετϥΫνϟϨΠϠ

    View full-size slide

  35. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΧʔτʹೖΕΔ"1*
    1045ϦΫΤετ͔Β঎඼*%ͱ঎඼ݸ਺Λऔಘ
    σʔλϕʔε͔Β঎඼*%Ͱ঎඼Λऔಘ
    Χʔτʹ঎඼ΛೖΕΔ
    ΧʔτΛηογϣϯʹอଘ
    ϨεϙϯεΛฦ͢

    View full-size slide

  36. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΠϯϑϥετϥΫνϟϨΠϠ
    wσʔλετΞ΍ϝʔϧૹ৴ɺ֎෦"1*࿈ܞͳͲ

    Ұൠతͳٕज़ػೳΛఏڙ͢ΔϨΠϠ
    wϦϙδτϦɺΩϟογϡɺ"1*ΫϥΠΞϯτͳͲ
    w&MPRVFOU2VFSZ#VJMEFS$BDIF

    View full-size slide

  37. D
    .BTBTIJ4IJOCBSB!TIJOY
    ϦϙδτϦ
    wϞσϧͱσʔλετΞͷؒʹհࡏ͠ɺ෼཭
    wσʔλετΞ͔ΒͷϞσϧͷऔಘɺอଘૢ࡞Λ

    ΠϯλʔϑΣΠεͰఆٛ
    wσʔλετΞʹԠͯ͡ɺΠϯλʔϑΣΠεΛ࣮૷

    σʔλϕʔεɺ,74ɺϝϞϦͳͲ

    View full-size slide

  38. D
    .BTBTIJ4IJOCBSB!TIJOY
    ঎඼৘ใͷऔಘ
    wυϝΠϯϞσϧ*UFNΫϥε
    wσʔλϕʔεJUFNTςʔϒϧ
    w*UFN*EΛҾ਺ʹऔΓɺ߹க͢Δ*UFNΛฦ͢

    View full-size slide

  39. ΠϯϑϥετϥΫνϟ
    $POUSPMMFS
    %BUB5SBOTGFS0CKFDU
    3FQPTJUPSZ*OUFSGBDF
    'PSN3FRVFTU
    "QQMJDBUJPO4FSWJDF
    ϑΝΠϧߏ੒%PNBJOϨΠϠ
    ϦϙδτϦ
    ΠϯλʔϑΣΠε

    View full-size slide

  40. &MPRVFOU
    3FQPTJUPSZ
    interface ItemRepository

    {

    public function findById(ItemId $id): Item;

    }
    *UFN3FQPTJUPSZ

    View full-size slide

  41. ΠϯϑϥετϥΫνϟ
    $POUSPMMFS
    %BUB5SBOTGFS0CKFDU
    3FQPTJUPSZ*OUFSGBDF
    'PSN3FRVFTU
    "QQMJDBUJPO4FSWJDF
    ϑΝΠϧߏ੒*OGSBTUSVDUVSF
    ϦϙδτϦ
    &MPRVFOU

    View full-size slide

  42. &MPRVFOU
    3FQPTJUPSZ
    class EloquentItemRepository implements ItemRepository

    {

    private $eloquent;


    public function __construct(EloquentItem $eloquent)

    {

    $this->eloquent = $eloquent;

    }


    public function findById(ItemId $id): Item

    {

    $item = $this->eloquent->find($id->value());

    if (empty($item)) {

    throw new NotFoundException('item not found');

    }


    return $item->toDomain();

    }

    }
    &MPRVFOU*UFN3FQPTJUPSZ

    View full-size slide

  43. &MPRVFOU
    3FQPTJUPSZ
    class EloquentItemRepository implements ItemRepository

    {

    private $eloquent;


    public function __construct(EloquentItem $eloquent)

    {

    $this->eloquent = $eloquent;

    }


    public function findById(ItemId $id): Item

    {

    $item = $this->eloquent->find($id->value());

    if (empty($item)) {

    throw new NotFoundException('item not found');

    }


    return $item->toDomain();

    }

    }
    &MPRVFOU*UFN3FQPTJUPSZ

    View full-size slide

  44. &MPRVFOU
    3FQPTJUPSZ
    class EloquentItem extends AppEloquent implements Domainable

    {

    protected $table = 'items';


    public function toDomain(): Item

    {

    return new Item(

    new ItemId($this->id),

    $this->name,

    new ItemPrice($this->price),

    new Stock($this->stock)

    );

    }

    }
    &MPRVFOU*UFN

    View full-size slide

  45. &MPRVFOU
    3FQPTJUPSZ
    class RepositoryServiceProvider extends ServiceProvider

    {

    public function register()

    {

    $this->app->bind(ItemRepository::class,
    EloquentItemRepository::class);

    }

    }
    ϦϙδτϦΛαʔϏείϯςφ΁όΠϯυ

    View full-size slide

  46. &MPRVFOU
    3FQPTJUPSZ
    class AddItemToCart

    {

    private $itemRepo;


    public function __construct(ItemRepository $itemRepo)

    {

    $this->itemRepo = $itemRepo;

    }


    public function add(int $itemId, int $count): Cart

    {

    $item = $this->itemRepo->findById(new ItemId($itemId));

    // (snip)

    }

    }

    ར༻ίʔυ

    View full-size slide

  47. D
    .BTBTIJ4IJOCBSB!TIJOY
    ϦϙδτϦ&MPRVFOU
    w&MPRVFOUΛ1FSTJTUFODF.PEFMʹ࢖͏
    wΠϯϑϥετϥΫνϟϨΠϠͷ

    ϦϙδτϦ࣮૷ʹด͡ࠐΊΔ
    wଞϨΠϠͰ&MPRVFOU͸جຊ࢖Θͳ͍

    ʢϑϨʔϜϫʔΫར༻࣌͸আ͘ʣ

    View full-size slide

  48. D
    .BTBTIJ4IJOCBSB!TIJOY
    ϦϙδτϦͷϝϦοτ
    wσʔλετΞ΍ΞΫηεखஈͷ੾ସ͕༰қ

    ຊ൪͸1PTUHSF42-ςετ͸ϝϞϦ
    wυϝΠϯϨΠϠ͔ΒσʔλετΞ΁ͷ࣮૷Λഉআ

    υϝΠϯϨΠϠ͸ΠϯλʔϑΣΠεͷϝιουΛݺͿ͚ͩ
    wඞཁͳσʔλετΞ΁ͷૢ࡞Λ໌ࣔ

    7BMVF0CKFDUͱಉ༷

    View full-size slide

  49. ΞϓϦέʔγϣϯϨΠϠ

    View full-size slide

  50. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΧʔτʹೖΕΔ"1*
    1045ϦΫΤετ͔Β঎඼*%ͱ঎඼ݸ਺Λऔಘ
    σʔλϕʔε͔Β঎඼*%Ͱ঎඼Λऔಘ
    Χʔτʹ঎඼ΛೖΕΔ
    ΧʔτΛηογϣϯʹอଘ
    ϨεϙϯεΛฦ͢

    View full-size slide

  51. D
    .BTBTIJ4IJOCBSB!TIJOY
    ΞϓϦέʔγϣϯϨΠϠ
    wγεςϜͷίϯτϩʔϧΛ୲͏ϨΠϠ
    wϢʔεέʔεͷྲྀΕΛ࡞Γɺ۩ମతͳॲཧ͸

    υϝΠϯ΍ΠϯϑϥετϥΫνϟʹҕৡ
    w3PVUF$POUSPMMFS"QQMJDBUJPO4FSWJDF

    View full-size slide

  52. &MPRVFOU
    3FQPTJUPSZ
    public function post(Request $request, AddItemToCart $service): JsonResponse

    {

    $this->validate($request, [

    'item_id' => 'required|integer',

    'count' => 'required|integer'

    ]);


    $cart = $service->add(

    $request->get('item_id'),

    $request->get('count')

    );


    return $this->ok(['cart' => $this->cartToArray($cart)]);

    }
    $POUSPMMFS
    ͬ͘͟ΓόϦσʔγϣϯ

    ʢυϝΠϯϧʔϧ͸υϝΠϯϨΠϠͰʣ

    View full-size slide

  53. &MPRVFOU
    3FQPTJUPSZ
    public function post(Request $request, AddItemToCart $service): JsonResponse

    {

    $this->validate($request, [

    'item_id' => 'required|integer',

    'count' => 'required|integer'

    ]);


    $cart = $service->add(

    $request->get('item_id'),

    $request->get('count')

    );


    return $this->ok(['cart' => $this->cartToArray($cart)]);

    }
    $POUSPMMFS
    ΞϓϦέʔγϣϯαʔϏε࣮ߦ

    View full-size slide

  54. &MPRVFOU
    3FQPTJUPSZ
    public function add(int $itemId, int $count): Cart

    {

    $item = $this->itemRepo->findById(new ItemId($itemId));


    try {

    $cart = $this->cartRepo->find();

    } catch (NotFoundException $e) {

    $cart = new Cart();

    }


    $cart->addItem($item, new ItemCount($count));

    $this->cartRepo->store($cart);


    return $cart;

    }

    "QQMJDBUJPO4FSWJDF

    View full-size slide

  55. D
    .BTBTIJ4IJOCBSB!TIJOY
    ·ͱΊ
    wυϝΠϯϨΠϠ͕ओɺͦΕҎ֎͸ै

    υϝΠϯϨΠϠͦ͜ΞϓϦέʔγϣϯ

    มԽͷૣ͍-BSBWFM͔ͩΒͦ͜
    wυϝΠϯʹಛԽ࣮ͨ͠૷
    w-BSBWFM͸ࣗ༝౓ͷߴ͍ϑϨʔϜϫʔΫ
    w஌ݟΛͲΜͲΜڞ༗͠Α͏ʂ

    View full-size slide

  56. D
    .BTBTIJ4IJOCBSB!TIJOY
    !TIJOY
    !TIJOY
    D
    .BTBTIJ4IJOCBSB!TIJOY

    View full-size slide

  57. D
    .BTBTIJ4IJOCBSB!TIJOY
    ͲΕ͔Β͸͡ΊΔʁ
    7BMVF0CKFDU

    View full-size slide

  58. D
    .BTBTIJ4IJOCBSB!TIJOY
    ୈҰาͱͯ͠
    w੍໿͕͋Δ΋ͷɺԋࢉΛߦ͏΋ͷΛ70Խ
    wՁ֨ɺ೔෇ɺಛघͳ஋ʢ঎඼ίʔυͱ͔ʣ
    wJOUʹͯ͠΋ɺ$BSCPOʹͯ͠΋ૢ࡞͕๛෋

    υϝΠϯͰٻΊΒΕ͍ͯΔૢ࡞͕ݟ͑ͳ͍

    ஀ੜ೔ʹ࣌ؒ΍೔෇ͷ଍͠ࢉͱ͔͍Βͳ͍
    wυϝΠϯಛԽܕͱͯ͠ΫϥεԽ

    View full-size slide

  59. &MPRVFOU
    3FQPTJUPSZ
    class DateOfBirth

    {

    /** @var Carbon */

    private $date;


    public function __construct(Carbon $date)

    {

    $this->date = $date;

    }


    public function age(): int

    {

    return $this->date->age;

    }

    }
    ੜ೥݄೔Λ7BMVF0CKFDUԽ
    $BSCPOΛϥοϓ
    ඞཁͳૢ࡞ͷΈ࣮૷

    View full-size slide

  60. D
    .BTBTIJ4IJOCBSB!TIJOY
    શ෦7BMVF0CKFDUʹ͢Δʁ
    w࣮ࡍɺखؒ͸͔͔Δ
    wJEʢJOUʣɺOBNFʢTUSJOHʣ͸70ʹͤͣ
    w70ʹ͢ΔͱɺϢϏΩλεݴޠΛਂ͘ߟ͑Δ

    ੍໿ɺඞཁͳૢ࡞
    wڽू౓ͷߴ͍খ͞ͳΫϥεͷ࢖͍উखͷྑ͞

    ͜Εͦ͜ɺΦϒδΣΫτࢦ޲։ൃ

    View full-size slide