契約による設計の紹介

 契約による設計の紹介

7e8bb5931a14030dc6a297aa364197bf?s=128

hakobe (Yohei Fushii)

August 25, 2016
Tweet

Transcript

  1. ܖ໿ʹΑΔઃܭͷ঺հ hakobe932

  2. ࿩୊: ؔ਺ͷೖྗ΍ग़ྗͷ νΣοΫͲ͏ͯ͠·͔͢?

  3. ؔ਺ͷ࢓༷: 
 τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠
 ಘΒΕͨ಺༰Λฦ͢ sub retrieve_content_by_token_1 { my ($token) =

    @_; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return $res->content; } ↑ ԿͷΤϥʔνΣοΫ΋ͳ͍ ۭจࣈྻͩͬͨΒ ϦΫΤετࣦഊͯͨ͠Β
  4. sub retrieve_content_by_token_return { my ($token) = @_; return unless $token;

    my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return if $res->is_error; return $res->content; } Կ͔͓͔͠ͳ͜ͱ͕ىͬͨ͜ΒِʹͳΔ஋Λฦ͢ ͓͔͔ͬͨ͠ΒSFUVSO ͬͪ͜΋ ྑ͘ͳ͍͜ͱ͕ىͬͨ͜Βِ஋
  5. sub retrieve_content_by_token_3 { my ($token) = @_; $token //= 'DEFAULT_TOKEN';

    my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return Failure->new($res->code) if $res->is_error; return Success->new($res->content); } ͱʹ͔͘ݺͼग़ͤΔ/݁Ռͷදݱ͸2छྨ ࣦഊͨ͠Β'BJMVSFΦϒδΣΫτ ੒ޭͨ͠Β4VDDFTTΦϒδΣΫτ ͳΔ΂͘Ժศʹࡁ·͢ ೖྗ͕͓͔͔ͬͨ͠ΒσϑΥϧτ஋
  6. sub retrieve_content_by_token_die { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); die 'request error: ' . $res->content if $res->is_error; return $res->content; } ॲཧ͕ࣦഊͨ͠Βྫ֎Λൃੜͤ͞Δ ෆਖ਼ͳೖྗ͸ڐ͞ͳ͍ ྫ֎ͰͳΜͱ͔͢Δ
  7. Ͳͷೖྗݕࠪॲཧ͕ྑ͍Ͱ͠ΐ͏? ❖ ྑ͘ͳ͍͜ͱ͕ىͬͨ͜Βِ஋ ❖ ͳΔ΂͘Ժศʹࡁ·͢ ❖ ྫ֎ͰͳΜͱ͔͢Δ

  8. ਖ਼ղ: Θͨ͠͸޷͖ʹͨ͠ ͲͷΑ͏ʹߟ͑Δ΂͖͔ͷࢦ਑͸͋Δ ܅Β΋޷͖ʹ͠Ζ

  9. ߟ͑Δ΂͖͜ͱ: ؔ਺ͷ࢓༷

  10. έʔεελσΟʹ͓͚Δؔ਺ͷ࢓༷ •τʔΫϯΛड͚औΓ •HTTPϦΫΤετͯ͠ •ಘΒΕͨ಺༰Λฦ͢ ←ਖ਼͍͠ೖྗ͕ಘΒΕͨ࣌ ←Կ͔࢓ࣄΛͯ͠
 ←ظ଴͞ΕΔ݁ՌΛฦ͢

  11. έʔεελσΟʹ͓͚Δؔ਺ͷ࢓༷ (Cont. •τʔΫϯΛड͚औΓ •HTTPϦΫΤετͯ͠ •ಘΒΕͨ಺༰Λฦ͢ ←ࣄલ৚݅Λຬͨͤ͹ ←Կ͔࢓ࣄΛͯ͠
 ←ࣄޙ৚݅Λຬͨ͢ ؔ਺ͷར༻ऀ͕ ؔ਺͸

  12. Q: ΋͠৚͕݅ຬͨͤͳ͍ͱͲ͏ͳΔ? ❖ ࣄલ৚͕݅ຬͨͤͳ͍ • ex.τʔΫϯ͕౉͞Εͳ͔ͬͨ • HTTPϦΫΤετΛ͢ΔͨΊͷURL͕ߏஙͰ͖ͳ͍ ❖ ࣄޙ৚͕݅ຬͨͤͳ͍

    • ex. HTTPϦΫΤετ͕ࣦഊͨ͠ • ฦ͢΂͖ίϯςϯπ͕࡞Εͳ͍ A: ؔ਺͸໨తΛՌͨͤͳ͍ ؔ਺Λ࣮ߦͨ݁͠ՌɺԿ͕ى͜Δ͔͸ෆఆ
  13. ࣄલ৚݅ͱࣄޙ৚݅ͷද໌ ❖ ؔ਺Λਖ਼͘͠ಈ͘ͷʹඞཁͳ৚݅Λද໌͢Δ # 事前条件: $token は必ず渡される必要がある # 事後条件: 取得したコンテンツは必ず返却される

    sub retrieve_content { my ($token) = @_; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return $res->content; }
  14. use Carp::Assert; sub retrieve_content_assert { my ($token) = @_; assert($token);

    my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); assert($res->is_success && $res->content); return $res->content; } ίʔυͰදݱ͢Δͱ࣮ߦ࣌ʹνΣοΫͰ͖Δ ίʔυʹΑΔද໌ͷදݱ(Carp::Assert) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
  15. sub retrieve_content_by_token_die { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); die 'request error: ' . $res->content if $res->is_error; return $res->content; } PerlͰ͸ૉ๿ʹྫ֎ʹΑΓදݱ͢Δ͘Β͍͕Ұൠత ίʔυʹΑΔද໌ͷදݱ(ྫ֎ ) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
  16. sub retrieve_content_by_token_die { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); die 'request error: ' . $res->content if $res->is_error; return $res->content; } ؔ਺ͷ࢓༷ʹج͍࣮ͮͨ૷ τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ಘΒΕͨ ಺༰Λฦ͢
  17. ܖ໿ʹΑΔઃܭ (Design by Contract) ❖ ࣄલ৚݅ͱࣄޙ৚݅ͱ͍͏એݴతͳੑ࣭ʹج͍ͮͯ
 ؔ਺Λઃܭ͢Δ ❖ ؔ਺ͱͦͷར༻ऀͷؒʹ͸ˢͷΑ͏ͳܖ໿͕͋Δͱ
 ଊ͑Δ

    ʮ΋ͦͪ͠Β͕ࣄલ৚݅Λຬͨͨ͠ঢ়ଶͰࢲΛ ݺͿͱ໿ଋͯ͠Լ͞ΔͳΒ͹ɺ
 ͓ฦ͠ʹࣄޙ৚݅Λຬͨ͢ঢ়ଶΛ࠷ऴతʹ࣮ݱ ͢Δ͜ͱΛ͓໿ଋ͠·͢ʯ
  18. ܖ໿ʹΑΔઃܭͷར఺ ❖ ਖ਼͍͠ίʔυΛॻ͘ॿ͚ʹͳΔ • ਖ਼͍ؔ͠਺ͷ࢖͍ํ͕໌֬ʹͳΔ • ·͕͍ͪʹૣ͘ؾ͚ͮΔ • → ιϑτ΢ΣΞͷ৴པੑ͕޲্͢Δ

    ❖ ؔ਺ͷੑ࣭Λ෼ੳ͢Δνϟϯε͕ಘΒΕΔ ❖ ؔ਺ͷੑ࣭Λදݱ͢ΔυΩϡϝϯτʹͳΔ
  19. Q:Τϥʔ͸ͳΜͰ΋ྫ֎ʹ͢Δ࿩? ❖ ΋͏͢͜͠ৄ͘͠ • ؔ਺ͷ࢓༷Λਖ਼͘͠ఆٛ͠Α͏ • ཁٻܕͷؔ਺/อޢܕͷؔ਺ • ৴པͰ͖ͳ͍ೖྗ͸༧ΊνΣοΫ͠Α͏ A:

    ͦ͏Ͱ͸ͳ͍
  20. sub retrieve_content_by_token_die { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); die 'request error: ' . $res->content if $res->is_error; return $res->content; } ؔ਺ͷ࢓༷ʹج͍࣮ͮͨ૷(࠶ܝ) τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ಘΒΕͨ ಺༰Λฦ͢ Τϥʔͷ಺༰ʹԠͯ͡
 ॲཧΛ੾Γସ͍͑ͨ
  21. ؔ਺ͷ࢓༷Λద੾ʹఆٛ͠Α͏ τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ಘΒΕͨ ಺༰Λฦ͢ τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ ੒ޭ͢Ε͹ಘΒΕͨ಺༰Λฦ͢ ࣦഊ͢Ε͹ΤϥʔͷछྨΛฦ͢ ؔ਺ͱͷద੾ͳܖ໿ؔ܎Λߟ͑Δ → ઃܭ

  22. sub retrieve_content_by_token_2 { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return Failure->new($res->code) if $res->is_error; return Success->new($res->content); } ࣄલ৚݅Λຬͨͯ͠ͳ͍ͷͰྫ֎ ੒ޭͨ͠Β4VDDFTTΦϒδΣΫτ ৽͍ؔ͠਺ͷ࢓༷ʹج͍࣮ͨ૷ ࣦഊͨ͠Β'BJMVSFΦϒδΣΫτ τʔΫϯΛड͚औΓ
 HTTPϦΫΤετͯ͠ ੒ޭ͢Ε͹ಘΒΕͨ಺༰Λฦ͢/ࣦഊ͢Ε͹ΤϥʔͷछྨΛฦ͢
  23. sub retrieve_content_by_token_3 { my ($token) = @_; $token //= 'DEFAULT_TOKEN';

    my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return Failure->new($res->code) if $res->is_error; return Success->new($res->content); } τʔΫϯͳ͚Ε͹σϑΥϧτ஋ ੒ޭͨ͠Β4VDDFTTΦϒδΣΫτ ͞Βʹࣄલ৚݅ΛΏΔΊΔ͜ͱ΋Ͱ͖Δ ࣦഊͨ͠Β'BJMVSFΦϒδΣΫτ τʔΫϯΛड͚औΔ͕ɺͳ͚Ε͹σϑΥϧτ஋Λ࢖͍
 HTTPϦΫΤετͯ͠ ੒ޭ͢Ε͹ಘΒΕͨ಺༰Λฦ͢/ࣦഊ͢Ε͹ΤϥʔͷछྨΛฦ͢
  24. ཁٻܕͷؔ਺ͱอޢܕͷؔ਺ ❖ ཁٻܕͷؔ਺ • ݺͼग़͠ଆ͕ࣄલ৚݅Λຬͨ͢͜ͱΛཁٻ͢Δؔ਺ • ex. ͢΂ͯͷ৔ॴͰྫ֎Λ࢖͍ͬͯͨύλʔϯ ❖ อޢܕͷؔ਺

    • ͲΜͳೖྗͰ΋ͳΜͱͯ͠ॲཧ͢Δؔ਺ • ex. Ұ൪৚݅ΛΏΔΊͨύλʔϯ ͲͪΒ͕ྑ͍͔͸ɺ࣌ͱ৔߹ɺ޷ΈʹΑΔ
  25. ཁٻܕ͕͓͢͢Ί(υϝΠϯϩδοΫͰ͸) ❖ ࢖͏ଆʹڧ͍৚݅Λ՝͢͜ͱͰؔ਺͕ਖ਼͘͠ಈ࡞͢Δ ͜ͱΛڧ੍Ͱ͖Δ ❖ ҟৗͳೖྗΛॲཧ͢Δίʔυ͕ͳ͘ͳΓίΞϩδοΫ ʹूதͨ͠γϯϓϧͳίʔυʹͳΔ ❖ ҟৗͳೖྗΛͲͷΑ͏ʹ੍ޚ͢Δ͔͸࢖͏ଆͷΈͰ
 ܾΊΔͷͰ੹೚ͷॴࡏ͕໌Β͔

  26. sub retrieve_content_by_token_3 { my ($token) = @_; $token //= 'DEFAULT_TOKEN';

    my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return Failure->new($res->code) if $res->is_error; return Success->new($res->content); } Ҿ਺Λ౉͠Θ͢Εͯͯ΋ಈ͘ อޢܕͷؔ਺ͷ৔߹ ຊ࣭తͰͳ͍ॲཧ͕૿͑Δ ೖྗ஋ݕࠪͷ੹೚͕ᐆດʹ
  27. sub retrieve_content_by_token_die { my ($token) = @_; die 'no token'

    unless $token; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); die 'request error: ' . $res->content if $res->is_error; return $res->content; } ཁٻܕͷؔ਺ͷ৔߹ ෆਖ਼ͳݺͼग़͠͸Τϥʔ ࢓༷ʹԊ͏ݕࠪͷΈΛߦ͏ ೖྗ஋ݕࠪͷ੹೚͸ݺͼग़͠ଆ
  28. my $input_token = <STDIN>; if (!$input_token) { print "Please input

    token"; exit 1; } my $content = retrieve_content_by_token_die($token); ࣄલ৚݅ΛνΣοΫͯ͠ݺͼग़͢ ࣄલ৚݅Λຬͨ͢͜ͱͷνΣοΫ ҆৺ͯ͠ݺͼग़͢ Ϟσϧͷ
 ϩδοΫ Ϣʔβೖྗ ϑΟϧλ
  29. ؔ਺ͷ࢓༷͸Ͳ͏΍ܾͬͯΊΔͷ͔? ❖ ؔ਺ʹͲͷΑ͏ͳ੹೚Λ༩͑Δͷ͔͸
 ؔ਺ͷଐ͢ΔΫϥε΍Ϟδϡʔϧʹґଘ͢Δ ❖ Ϋϥε΍Ϟδϡʔϧͷ੹೚͸
 ιϑτ΢ΣΞͷΞʔΩςΫνϟʹґଘ͢Δ ࡉ෦ͷઃܭ͸શମͷઃܭʹجͮ͘

  30. ϨΠϠͷ͋ΔΞʔΩςΫνϟͷ৔߹ Ϣʔβೖྗ • ೖྗͷνΣοΫ • νΣοΫOK
 → ϩδοΫݺͿ • νΣοΫNG


    → ΤϥʔΛฦ͢ • ೖྗΛ৴པͯ͠
 υϝΠϯϩδοΫ
 Λ࣮ߦ อޢܕͷϝιου ཁٻܕͷϝιου ΠϯλʔϑΣʔε υϝΠϯϩδοΫ ݺͼग़͠ ϨΠϠͷ੹೚ʹରԠ͢Δ
  31. ܖ໿ʹΑΔઃܭ͸ؔ਺ʹݶΒͳ͍ ❖ ؔ਺͸୅දత͚ͩͲଞͷ෦෼ʹ΋ద༻Ͱ͖Δ • Ϋϥε: ΦϒδΣΫτͷෆม৚݅ • ϧʔϓ: ϧʔϓෆม৚݅ ίϯϙʔωϯτͷཁٻΛຬͨ͢͜ͱͰརӹΛಘΔ

  32. ৄ͘͠͸ΦϒδΣΫτࢦ޲ೖ໳Λಡ΋͏ ❖ ιϑτ΢ΣΞઃܭͷຊ ❖ ιϑτ΢ΣΞ඼࣭ͷఆٛ΍ ྺ࢙ΛͨͲֶͬͯ΂Δ ❖ ༗ӹ͚ͩͲྔ͕͓͓͍ • 1800ϖʔδ͘Β͍

    • ͕Μ͹Ζ͏
  33. ιϑτ΢ΣΞΞʔΩςΫνϟ͕ؾʹͳΔਓ޲͚ https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html Clean Architecture

  34. ·ͱΊ ❖ ʮܖ໿ʹΑΔઃܭʯ͸ਖ਼͍͠ίʔυͷͨΊͷςΫχοΫ • ؔ਺ͷ࢓༷Λࣄલ৚݅ͱࣄޙ৚͔݅ΒͳΔܖ໿ͱଊ͑Α͏ • ܖ໿ʹج͍ͮͯίʔυΛ࣮૷͠Α͏ ❖ ؔ਺ͱͷܖ໿͸ιϑτ΢ΣΞΞʔΩςΫνϟΛݩʹ
 ߟ͑Α͏

    • Ϋϥε΍ϨΠϠͷ੹೚Λ෼ੳͯ͠ରԠͨ͠੹೚Λ༩͑Α͏ • ཁٻܕͱอޢܕΛҙࣝͯ͠࢖͍Θ͚Α͏
  35. ๷ޚతϓϩάϥϛϯά͸Ͳ͜΁? ❖ Կ͕ى͜Δ͔Θ͔Βͳ͍ͷͰݸʑͷؔ਺͸ͳΔ΂͘
 ͋ΒΏΔೖྗνΣοΫ ❖ ؔ਺ͷఆٛͱݺͼग़͠͸ܖ໿ͱ͍͏ܗͰ੔ཧ͞Ε͍ͯ Ε͹γϯϓϧͳίʔυͱ໌͕֬͞ҡ࣋͞ΕΔ