制約でコードに秩序を

 制約でコードに秩序を

2016/05/21 PHP カンファレンス福岡 2016

Ca17a082a30f4cbfed1d0a6dacbe3af2?s=128

shin1x1

May 21, 2016
Tweet

Transcript

  1. ɹ!shin1x1 2016/05/21 1)1ΧϯϑΝϨϯε෱Ԭ ੍໿ͰίʔυʹடংΛ

  2. ੍໿ͱ͸

  3. ੍ݶ΍৚݅Λ͚ͭͯ ࣗ༝ʹ׆ಈͤ͞ͳ͍͜ͱ https://kotobank.jp/word/%E5%88%B6%E7%B4%84-546519

  4. ੍ݶ΍৚݅Λ͚ͭͯ ࣗ༝ʹ׆ಈͤ͞ͳ͍͜ͱ https://kotobank.jp/word/%E5%88%B6%E7%B4%84-546519

  5. ࠓ೔ͷ୊ࡐ

  6. &$αΠτ γϣοϐϯάΧʔτ

  7. Χʔτʹ௥Ճ

  8. ΧʔτΛදࣔ

  9. <DBTF> Χʔτʹ঎඼Λ௥Ճ

  10. D .BTBTIJ4IJOCBSB!TIJOY Χʔτʹ঎඼Λ௥Ճ wΧʔτ$BSUΫϥε w঎඼*UFNΫϥε w$BSUJUFNTʹ঎඼Λ௥Ճ

  11. *UFN class Item
 {
 public $code;
 public $price;
 
 public

    function __construct(string $code, int $price)
 {
 $this->code = $code;
 $this->price = $price;
 }
 }
  12. $BSU class Cart
 {
 public $items;
 
 public function __construct()


    {
 $this->items = [];
 }
 
 public function calculateTotalPrice(): int
 {
 $totalPrice = 0;
 
 foreach ($this->items as $item) {
 $totalPrice = $totalPrice + $item->price;
 }
 
 return $totalPrice;
 }
 }
  13. D .BTBTIJ4IJOCBSB!TIJOY ঎඼௥ՃΛ*UFNΫϥεʹݶఆ w$BSUJUFNTΛQSJWBUFͰӅ͢ wBEE*UFNϝιουΛ௥Ճ wλΠϓώϯςΟϯάͰ*UFNΫϥεʹݶఆ

  14. $BSU class Cart
 {
 private $items;
 
 public function __construct()


    {
 $this->items = [];
 }
 
 public function addItem(Item $item)
 {
 $this->items[] = $item;
 }
 (snip) } QSJWBUF λΠϓώϯςΟϯά
  15. D .BTBTIJ4IJOCBSB!TIJOY ΞΫηεम০ࢠλΠϓώϯςΟϯά wΫϥεࣗ਎͕ϓϩύςΟΛίϯτϩʔϧ wΫϥε֎ʹίϯτϩʔϧΛ౉͞ͳ͍ wૢ࡞ํ๏Λݶఆ͍ͯ͠Δ͔Βͦ͜
 ίϯτϩʔϧͰ͖Δ
 ʢλΠϓώϯςΟϯάͳͲʣ

  16. <DBTF> Χʔτͷ঎඼఺਺͸ ఺·Ͱ

  17. D .BTBTIJ4IJOCBSB!TIJOY Χʔτͷ঎඼఺਺͸఺Ҏ಺ w఺Ҏ্ͷ঎඼Λ֨ೲ͠Α͏ͱͨ͠Βྫ֎ൃੜ w঎඼௥ՃͷࡍʹνΣοΫΛߦ͏

  18. D .BTBTIJ4IJOCBSB!TIJOY BEE*UFNϝιουͰ੍໿ wBEE*UFNϝιουͰ঎඼఺਺ΛνΣοΫ w͜ͷϝιουͰ͔͠$BSUJUFNTΛ
 มߋͰ͖ͳ͍ͷͰ༗ޮ wϓϩύςΟͷίϯτϩʔϧΛΫϥεࣗ਎͕ߦ͏
 QVCMJDͩͱ֎෦ʹίϯτϩʔϧ͞ΕΔ

  19. $BSU class Cart
 { (snip)
 public function addItem(Item $item)
 {


    if (count($this->items) >= 3) {
 throw new PreconditionException();
 }
 
 $this->items[] = $item;
 } (snip)
 }
  20. <DBTF> ঎඼খܭʹ ফඅ੫ΛՃࢉ

  21. D .BTBTIJ4IJOCBSB!TIJOY ੫ࠐՁ֨ࢉग़ wΧʔτͷ঎඼ͦΕͧΕʹফඅ੫ΛՃࢉ w੫ࠐΈՁ֨ͷ߹ܭΛখܭՁ֨ͱ͢Δ

  22. $BSU $cart = new Cart();
 
 $item1 = new Item('code1',

    100);
 $cart->addItem($item1);
 
 $item2 = new Item('code2', 200);
 $cart->addItem($item2);
 
 $this->assertEquals(324, $cart->calculateTotalPrice());
 $this->assertEquals(324, $cart->calculateTotalPrice()); ʹͳΔʁʁʁ
  23. $BSU class Cart
 { (snip)
 public function calculateTotalPrice(): int
 {


    $totalPrice = 0;
 
 foreach ($this->items as $item) {
 $item->price = (int)($item->price * 1.08);
 $totalPrice = $totalPrice + $item->price;
 }
 
 return $totalPrice;
 } (snip)
 } *UFNQSJDF͕ มߋ͞ΕΔ ճݺͿͱ ͞ΒʹഒʹͳΔ
  24. D .BTBTIJ4IJOCBSB!TIJOY *UFNΫϥεΛෆมʹ͢Δ w׬શίϯετϥΫλ
 ίϯετϥΫλͰશͯͷ஋Λ༩͑Δ wෆมʢΠϛϡʔλϒϧʣΫϥε
 QSJDF ͸ৗʹಉ͡஋Λฦ͢ wඞཁͳHFUUFSͷΈ࣮૷

  25. *UFN class Item
 {
 private $code;
 private $price;
 
 public

    function __construct(string $code, int $price)
 {
 $this->code = $code;
 $this->price = $price;
 }
 
 public function price(): int
 {
 return $this->price;
 }
 } QSJWBUF
  26. $BSU class Cart
 { (snip)
 public function calculateTotalPrice(): int
 {


    $totalPrice = 0;
 
 foreach ($this->items as $item) {
 $price = (int)($item->price() * 1.08);
 $totalPrice = $totalPrice + $price;
 }
 
 return $totalPrice;
 } (snip)
 } *UFNQSJDF͸ มߋͰ͖ͳ͍
  27. <DBTF> Ձ֨΁ͷૢ࡞Λݶఆ

  28. D .BTBTIJ4IJOCBSB!TIJOY Ձ֨ͷԋࢉΛ੍ݶ wJOUͩͱҙຯ͕޿͗͢ΔʢՄೳͳԋࢉ΋ଟ͍ʣ w଍͠ࢉͱ੫ࠐՁ֨ܭࢉʢֻ͚ࢉͰ͸ͳ͍ʣͷΈ wՁ֨Λ1SJDFΫϥεͰදݱ

  29. 1SJDF class Price
 {
 const TAX_RATE = 1.08;
 private $price;


    
 public function __construct(int $price)
 {
 $this->price = $price;
 }
 
 public function add(self $price): self
 {
 return new self($this->price + $price->price);
 }
 
 public function withTax(): self
 {
 return new self((int)($this->price * static::TAX_RATE));
 }
 
 public function toInt(): int
 {
 return $this->price;
 }
 }
  30. *UFN class Item
 {
 private $code;
 private $price;
 
 public

    function __construct(string $code, int $price)
 {
 $this->code = $code;
 $this->price = new Price($price);
 }
 
 public function price(): Price
 {
 return $this->price;
 }
 }
  31. $BSU class Cart
 { (snip)
 public function calculateTotalPrice(): Price
 {


    $totalPrice = new Price(0);
 
 foreach ($this->items as $item) {
 $price = $item->price()->withTax();
 $totalPrice = $totalPrice->add($price);
 }
 
 return $totalPrice;
 } (snip)
 } Ձ֨͸1SJDFͰදݱ ੫ࠐՁ֨ࢉग़ Ձ֨ͷ଍͠ࢉ
  32. D .BTBTIJ4IJOCBSB!TIJOY 7BMVF0CKFDU w஋ΛΫϥεͰදݱ wෆมΫϥε
 ԋࢉ݁Ռ͸৽͍͠ΠϯελϯεͰฦ͢ wඞཁͳԋࢉͷΈΛ࣮૷ w಺෦ͷ஋ΛӅณ

  33. <DBTF> ঎඼ɺΧʔτ৘ใΛ +40/Ͱग़ྗ

  34. D .BTBTIJ4IJOCBSB!TIJOY ঎඼ɺΧʔτ৘ใΛ+40/Ͱग़ྗ w+BWB4DSJQUΫϥΠΞϯτ΍
 εϚʔτϑΥϯΞϓϦ࿈ܞ w*UFNUP"SSBZ Ͱ഑ྻͱͯ͠ग़ྗ wKTPO@FODPEF Ͱ+40/ʹ͢Δ

  35. "QJ$POUSPMMFS class ApiController
 {
 public function item()
 {
 $item =

    new Item('code1', 100);
 $this->json($item);
 }
 
 private function json(Item $entity)
 {
 header('Content-Type: application/json');
 echo json_encode($entity->toArray());
 }
 }
  36. class ApiController
 {
 public function item()
 {
 $item = new

    Item('code1', 100);
 $this->json($item);
 }
 public function cart()
 {
 $cart = new Cart();
 $cart->addItem(new Item('code1', 100));
 $cart->addItem(new Item('code2', 200));
 
 $this->json($cart);
 } private function json(Item $entity)
 {
 header('Content-Type: application/json');
 echo json_encode($entity->toArray());
 }
 } DBSU͸
 *UFNΫϥεͰ͸ͳ͍
  37. D .BTBTIJ4IJOCBSB!TIJOY "SSBZBCMFΠϯλʔϑΣΠε w"QJ$POUSPMMFSKTPO ͕
 ඞཁͳґଘΛΠϯλʔϑΣΠεͰ໌ࣔ wΠϯλʔϑΣΠε࣮͑͞૷͍ͯ͠Ε͹
 ͲΜͳΫϥεͰ΋ྑ͍ w࢓༷ͱ࣮૷ͷ෼཭

  38. "SSBZBCMF interface Arrayable
 {
 public function toArray(): array;
 }

  39. *UFN class Item implements Arrayable
 {
 (snip) public function toArray():

    array
 {
 return [
 'code' => $this->code,
 'price' => $this->price->toInt(),
 ];
 }
 }
  40. $BSU class Cart implements Arrayable
 {
 (snip) public function toArray():

    array
 {
 return array_map(function (Item $item) {
 return $item->toArray();
 }, $this->items);
 }
 }
  41. class ApiController
 {
 public function item()
 {
 $item = new

    Item('code1', 100);
 $this->json($item);
 }
 public function cart()
 {
 $cart = new Cart();
 $cart->addItem(new Item('code1', 100));
 $cart->addItem(new Item('code2', 200));
 
 $this->json($cart);
 } private function json(Arryable $entity)
 {
 header('Content-Type: application/json');
 echo json_encode($entity->toArray());
 }
 } "SSBZBCMF
  42. D .BTBTIJ4IJOCBSB!TIJOY ˞ิ଍ 1)1ʹ͸ɺ+TPO4FSJBMJ[BCMFͱ͍͏
 ΠϯλʔϑΣΠε͕͋Γ·͢ɻ
 ΦϒδΣΫτΛ+40/Խ͢Δࡍ͸
 ࢀߟʹ͍ͯͩ͘͠͞ɻ http://php.net/manual/ja/class.jsonserializable.php

  43. ੍໿ͱ͸

  44. ࣗ༝Λୣ͏ ໘౗ͳ΋ͷͰ͸ͳ͘

  45. டংΛकΓ ҙਤΛ໌֬ʹ͢Δ΋ͷ ੍໿ ΘΜͺ͘ͳίʔυ https://flic.kr/p/4e5ggf ίʔυͷடংΛ कΔ΋ͷ

  46. ੍໿Ͱடং͋Δ։ൃΛʂ

  47. D .BTBTIJ4IJOCBSB!TIJOY !TIJOY !TIJOY D .BTBTIJ4IJOCBSB!TIJOY

  48. D .BTBTIJ4IJOCBSB!TIJOY QSPUFDUFEPSQSJWBUF w·ͣ͸ɺQSJWBUFඞཁͳΒQSPUFDUFE w͍͔ͭݺ͹ΕΔ͔΋͠Εͳ͍͔ΒQSPUFDUFE
 :"(/*ʢ:PVBJOUHPOOBOFFEJUʣ wଞਓ͕࡞ͬͨγεςϜΛϝϯςφϯε͢Δͱ
 QSJWBUFສࡀʹͳΔ wUSBJU͕͋ΔͷͰɺػೳͷͨΊʹܧঝ͢Δඞཁ͕ແ͍