PHPで
FizzBuzz問題をやってみよう #ゆるWeb札幌

PHPで
FizzBuzz問題をやってみよう #ゆるWeb札幌

PHPでFizzBuzz問題を解いていく。
シンプルな解き方から、段階的にオブジェクト指向を取り入れてみる。
ゆるWeb勉強会@札幌 #4
#ゆるWeb札幌

13725f35541aa680ed5f85d16b85947a?s=128

Kihara, Takuya

March 30, 2019
Tweet

Transcript

  1. PHPͰ
 FizzBuzz໰୊Λ
 ΍ͬͯΈΑ͏ 2019/03/30 tacck ゆるWeb勉強会@札幌 #4 #ゆるWeb札幌

  2. ୭ UBDDL ໊લ ࠷ۙ͸ݹͷ+BWBͷ͓कΓ ͓࢓ࣄ εϓϨουɾΠʔάϧ ޷͖ͳϑΟΪϡΞεέʔτͷٕ ΏΔ8FCࡳຈ

  3. ࠓ೔͓࿩͢͠Δ͜ͱ • FizzBuzz໰୊ • ΍ͬͯΈΑ͏ • റΓϓϨΠ ΏΔ8FCࡳຈ

  4. FizzBuzz໰୊ ΏΔ8FCࡳຈ

  5. FizzBuzz໰୊ • ϓϩάϥϚʔͷᅂΈ ΏΔ8FCࡳຈ

  6. FizzBuzz໰୊ • 3ͷഒ਺Ͱ “Fizz” ͱग़ྗ • 5ͷഒ਺Ͱ “Buzz” ͱग़ྗ •

    3ͷഒ਺ ͔ͭ 5ͷഒ਺Ͱ “FizzBuzz” ͱग़ྗ
 (ͭ·Γ15ͷഒ਺) • ͦΕҎ֎͸਺஋ࣗମΛจࣈͱͯ͠ग़ྗ ΏΔ8FCࡳຈ
  7. FizzBuzz໰୊ • ࠓճ͸ɺ • 1ʙ100·Ͱͷ੔਺஋Λ༩͑Δɻ • લͷϖʔδͷنଇʹैͬͯग़ྗ͢Δɻ • ͱ͍͏ϓϩάϥϜΛ࡞੒͍ͯ͘͠ɻ ΏΔ8FCࡳຈ

  8. ΍ͬͯΈΑ͏ ΏΔ8FCࡳຈ

  9. Step1: ૉ௚ͳ࣮૷ ΏΔ8FCࡳຈ

  10. ૉ௚ͳ࣮૷ • ࡉ͔͍͜ͱ͸ؾʹͤͣʹɻ https://github.com/tacck/PHPFizzBuzzTraining/tree/Step1 ΏΔ8FCࡳຈ

  11. <?php for ($num = 1; $num <= 100; $num++) {

    if ($num % 3 === 0 && $num % 5 === 0) { echo 'FizzBuzz' . PHP_EOL; } elseif ($num % 3 === 0 && $num % 5 !== 0) { echo 'Fizz' . PHP_EOL; } elseif ($num % 3 !== 0 && $num % 5 === 0) { echo 'Buzz' . PHP_EOL; } else { echo "$num" . PHP_EOL; } }
  12. Step2: ॳ৺ऀ޲͚ ΏΔ8FCࡳຈ

  13. ॳ৺ऀ޲͚ • FizzBuzzͷ൑ఆΛؔ਺(ϝιου)Խɻ https://github.com/tacck/PHPFizzBuzzTraining/tree/Step2 ΏΔ8FCࡳຈ

  14. <?php for ($num = 1; $num <= 100; $num++) {

    echo getFizzBuzz($num) . PHP_EOL; } function getFizzBuzz(int $num): string { if ($num % 3 === 0 && $num % 5 === 0) { return 'FizzBuzz'; } elseif ($num % 3 === 0 && $num % 5 !== 0) { return 'Fizz'; } elseif ($num % 3 !== 0 && $num % 5 === 0) { return 'Buzz'; } else { return "$num"; } }
  15. Step3: ॳ৺ऀΑΓ্Λ໨ࢦ͢ ΫϥεΛ࢖͏ ΏΔ8FCࡳຈ

  16. ΫϥεΛ࢖͏ • ໾ׂͷ෼୲ΛΫϥεͰදݱ͢Δɻ • 1ʙ100ͷ਺஋ʹରԠ͢ΔจࣈྻΛදࣔ • ਺஋ͱจࣈͷରԠؔ܎Λ൑ఆ͠ฦ٫ https://github.com/tacck/PHPFizzBuzzTraining/tree/Step3 ΏΔ8FCࡳຈ

  17. <?php require_once __DIR__ . '/vendor/autoload.php'; use App\FizzBuzz\FizzBuzz; $fizzBuzz = new

    FizzBuzz(); for ($num = 1; $num <= 100; $num++) { echo $fizzBuzz->getFizzBuzz($num) . PHP_EOL; }
  18. <?php namespace App\FizzBuzz; class FizzBuzz { public function getFizzBuzz(int $num):

    string { if ($num % 3 === 0 && $num % 5 === 0) { return 'FizzBuzz'; } elseif ($num % 3 === 0 && $num % 5 !== 0) { return 'Fizz'; } elseif ($num % 3 !== 0 && $num % 5 === 0) { return 'Buzz'; } else { return "$num"; } } }
  19. Step4: தڃऀ޲͚ Ϋϥεͷ੹೚Λ෼͚Δ ΏΔ8FCࡳຈ

  20. Ϋϥεͷ੹೚? • ͦͷΫϥε͕ʮҰͭͷ੹೚ʯʹด͍ͯ͡Δ͔ • ؔ৺ͷ෼཭ɺૄ݁߹ɺͱ͍ͬͨΩʔϫʔυɻ • 1ʙ100ͷ਺஋ʹରԠ͢ΔจࣈྻΛදࣔ • ਺஋ͱจࣈͷରԠؔ܎ͷ൑ఆ •

    ରԠ͢Δจࣈྻͷฦ٫ https://github.com/tacck/PHPFizzBuzzTraining/tree/Step4 ΏΔ8FCࡳຈ
  21. ؔ৺ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ • จࣈྻΛ֬ఆ͍ͤͨ͞ɻ ΏΔ8FCࡳຈ

  22. ؔ৺ͱ੹೚ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ
 ˠ ϝιουͷݺͼग़͠ͱ݁Ռͷग़ྗ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ
 ˠ ੔਺஋Λड͚औΓɺରԠ͢Δදࣔ಺༰ͷฦ٫ •

    දࣔ಺༰Λ֬ఆ͍ͤͨ͞ɻ
 ˠ ࣗ਎͕ར༻͞ΕΔ৔߹ʹදࣔ಺༰Λฦ٫ ΏΔ8FCࡳຈ
  23. ؔ৺ͱ੹೚ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ
 ˠ ϝιουͷݺͼग़͠ͱग़ྗ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ
 ˠ ੔਺஋Λड͚औΓɺରԠ͢Δදࣔ಺༰ͷฦ٫ •

    දࣔ಺༰Λ֬ఆ͍ͤͨ͞ɻ
 ˠ ࣗ਎͕ར༻͞ΕΔ৔߹ʹදࣔ಺༰Λฦ٫ ݺͼग़ͯ͠࢖͏ ݺͼग़ͯ͠࢖͏ ΏΔ8FCࡳຈ
  24. ؔ৺ͱ੹೚ ΏΔ8FCࡳຈ ΠϯλϑΣʔε ೖग़ྗ ͷ੹೚ ਖ਼͍͠σʔλΛड͚౉͢੹೚ ਖ਼͍͠σʔλͰ͋Δ੹೚ ґଘؔ܎͸
 Ұํ޲ ґଘؔ܎͸


    Ұํ޲
  25. <?php require_once __DIR__ . '/vendor/autoload.php'; use App\FizzBuzz\FizzBuzzPresenterBuilder; for ($num =

    1; $num <= 100; $num++) { echo FizzBuzzPresenterBuilder::build($num) . PHP_EOL; }
  26. <?php namespace App\FizzBuzz; use App\FizzBuzz\FizzBuzzPresenterInterface; class FizzBuzzPresenterBuilder { public static

    function build(int $num): FizzBuzzPresenterInterface { if ($num % 3 === 0 && $num % 5 === 0) { return new \App\FizzBuzz\Presenter\FizzBuzzPresenter($num); } elseif ($num % 3 === 0 && $num % 5 !== 0) { return new \App\FizzBuzz\Presenter\FizzPresenter($num); } elseif ($num % 3 !== 0 && $num % 5 === 0) { return new \App\FizzBuzz\Presenter\BuzzPresenter($num); } else { return new \App\FizzBuzz\Presenter\NumberPresenter($num); } } }
  27. <?php namespace App\FizzBuzz\Presenter; use App\FizzBuzz\FizzBuzzPresenterInterface; class FizzPresenter implements FizzBuzzPresenterInterface {

    private $num; public function __construct(int $num) { $this->num = $num; } public function __toString(): string { return 'Fizz'; } public function isAvailable(): bool { return true; } }
  28. Step5: റΓϓϨΠ ifจΛ࢖Θͳ͍Ͱ࣮૷͢Δ ΏΔ8FCࡳຈ

  29. ifจΛ࢖Θͳ͍Ͱ࣮૷͢Δ • ಄ͷମૢ ΏΔ8FCࡳຈ

  30. ifจΛ࢖Θͳ͍Ͱ࣮૷͢Δ • ಄ͷମૢ • ݱ࣮໰୊ͱͯ͠ɺ
 ଟ਺ͷ৚݅෼ذ͸όάΛੜΈ΍͍͢ɻ
 ˠ ʮଟ਺ʯͷ෦෼Λղ͖΄͙͢ https://github.com/tacck/PHPFizzBuzzTraining/tree/Step5 ΏΔ8FCࡳຈ

  31. ؔ৺ͱ੹೚ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ
 ˠ ϝιουͷݺͼग़͠ͱग़ྗ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ
 ˠ ੔਺஋Λड͚औΓɺରԠ͢Δදࣔ಺༰ͷฦ٫ •

    දࣔ಺༰Λ֬ఆ͍ͤͨ͞ɻ
 ˠ ࣗ਎͕ར༻͞ΕΔ৔߹ʹදࣔ಺༰Λฦ٫ ΏΔ8FCࡳຈ ͜͜ʹ৚݅෼ذ
  32. ؔ৺ͱ੹೚ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ
 ˠ ϝιουͷݺͼग़͠ͱग़ྗ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ
 ˠ ੔਺஋Λड͚औΓɺରԠ͢Δදࣔ಺༰ͷฦ٫ •

    දࣔ಺༰Λ֬ఆ͍ͤͨ͞ɻ
 ˠ ࣗ਎͕ར༻͞ΕΔ৔߹ʹදࣔ಺༰Λฦ٫ ΏΔ8FCࡳຈ ͜͜ʹ஫໨
  33. ؔ৺ͱ੹೚ • ಛఆͷ੔਺஋Λ༩͑ɺจࣈྻΛग़ྗ͍ͨ͠ɻ
 ˠ ϝιουͷݺͼग़͠ͱग़ྗ • ੔਺஋ͱจࣈྻͷରԠΛอূ͍ͨ͠ɻ
 ˠ ੔਺஋Λड͚औΓɺରԠ͢Δදࣔ಺༰ͷฦ٫ •

    දࣔ಺༰Λ֬ఆ͍ͤͨ͞ɻ
 ˠ ࣗ਎͕ར༻͞ΕΔ৔߹ʹදࣔ಺༰Λฦ٫ ΏΔ8FCࡳຈ ࢖͑Δ͔Ͳ͏͔͸ ʮදࣔ಺༰ʯࣗ਎͕஌Δ΂͖
  34. ؔ৺ͱ੹೚ ΏΔ8FCࡳຈ ΠϯλϑΣʔε ೖग़ྗ ͷ੹೚ ਖ਼͍͠σʔλΛड͚౉͢੹೚ ਖ਼͍͠σʔλͰ͋Δ੹೚

  35. <?php require_once __DIR__ . '/vendor/autoload.php'; use App\FizzBuzz\FizzBuzzPresenterBuilder; for ($num =

    1; $num <= 100; $num++) { echo FizzBuzzPresenterBuilder::build($num) . PHP_EOL; }
  36. <?php namespace App\FizzBuzz; use App\FizzBuzz\FizzBuzzPresenterInterface; class FizzBuzzPresenterBuilder { public static

    function build(int $num): FizzBuzzPresenterInterface { foreach (glob(__DIR__ . '/Presenter/Dynamic/*.php') as $file) { require_once $file; $class = '\App\FizzBuzz\Presenter\Dynamic\\' . basename($file, '.php'); $presenter = new $class($num); try { // throw ParseError if $num is not available $presenter->isAvailable(); return $presenter; } catch (\ParseError $e) { // none } } return new \App\FizzBuzz\Presenter\NumberPresenter($num); } }
  37. <?php namespace App\FizzBuzz\Presenter\Dynamic; use App\FizzBuzz\FizzBuzzPresenterInterface; class FizzPresenter implements FizzBuzzPresenterInterface {

    private $num; public function __construct(int $num) { $this->num = $num; } public function __toString(): string { return 'Fizz'; } public function isAvailable(): bool { return ($this->num % 3 === 0 && $this->num % 5 !== 0) ? true : eval('invalid'); } }
  38. ifจΛ࢖Θͳ͍Ͱ࣮૷͢Δ • Ԡ༻ྫ • ݩ߸໰୊ • ৽ݩ߸͕ൃද͞ΕͨΒɺ
 PresenterΫϥεΛ௥Ճ͢Δ͚ͩɻ https://github.com/tacck/PHPJapaneseEraTraining ΏΔ8FCࡳຈ

  39. ·ͱΊ ΏΔ8FCࡳຈ

  40. ·ͱΊ • FizzBuzz໰୊Λɺ
 ͍͔ͭ͘ͷܗͰղ͍ͯΈͨɻ • ΦϒδΣΫτࢦ޲ͷߟ͑ํΛ͏·͘࢖͏ͱɺ
 ҆શ͔֦ͭுੑΛߴ͘Ͱ͖Δɻ
 ˠ ࠓճ࢖ͬͨͷ͸
 ɹ

    ʮΦʔϓϯɾΫϩʔζυͷݪଇʯ • ಄ͷମૢΛ݉ͶͯɺറΓϓϨΠΛͯ͠ΈΑ͏! ΏΔ8FCࡳຈ
  41. ·ͱΊ • ੹೚ͷ෼͚ํɺؔ৺ͷ෼཭ɺ
 ࠷ॳ͸೉͍͠ɻ • ʮ͜ͷਓ(Ϋϥε)͸ԿΛ஌͍ͬͯΔ΂͖͔ʯ
 ʮ͜ͷਓ(Ϋϥε)ʹ͸ԿΛ஻ͬͯཉ͍͔͠ʯ
 ਓ(Ϋϥε)ͷؾ࣋ͪʹͳͬͯߟ͑Δɻ • TDD

    (ςετۦಈ։ൃ) Λ΍Δͱɺ
 ʮΫϥεʹ໰͍͔͚ͳ͕Βʯ։ൃͰ͖Δɻ ΏΔ8FCࡳຈ
  42. ࣍ճ༧ࠂ? • (PHPͰ)TDDΛ΍ͬͯΈΔ? ΏΔ8FCࡳຈ

  43. end ΏΔ8FCࡳຈ