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

契約による設計の紹介

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

 契約による設計の紹介

Avatar for hakobe (Yohei Fushii)

hakobe (Yohei Fushii)

August 25, 2016
Tweet

More Decks by hakobe (Yohei Fushii)

Other Decks in Programming

Transcript

  1. ؔ਺ͷ࢓༷: 
 τʔΫϯΛड͚औΓ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; } ↑ ԿͷΤϥʔνΣοΫ΋ͳ͍ ۭจࣈྻͩͬͨΒ ϦΫΤετࣦഊͯͨ͠Β
  2. 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 ͬͪ͜΋ ྑ͘ͳ͍͜ͱ͕ىͬͨ͜Βِ஋
  3. 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ΦϒδΣΫτ ͳΔ΂͘Ժศʹࡁ·͢ ೖྗ͕͓͔͔ͬͨ͠ΒσϑΥϧτ஋
  4. 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; } ॲཧ͕ࣦഊͨ͠Βྫ֎Λൃੜͤ͞Δ ෆਖ਼ͳೖྗ͸ڐ͞ͳ͍ ྫ֎ͰͳΜͱ͔͢Δ
  5. Q: ΋͠৚͕݅ຬͨͤͳ͍ͱͲ͏ͳΔ? ❖ ࣄલ৚͕݅ຬͨͤͳ͍ • ex.τʔΫϯ͕౉͞Εͳ͔ͬͨ • HTTPϦΫΤετΛ͢ΔͨΊͷURL͕ߏஙͰ͖ͳ͍ ❖ ࣄޙ৚͕݅ຬͨͤͳ͍

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

    sub retrieve_content { my ($token) = @_; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return $res->content; }
  7. 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) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
  8. 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Ͱ͸ૉ๿ʹྫ֎ʹΑΓදݱ͢Δ͘Β͍͕Ұൠత ίʔυʹΑΔද໌ͷදݱ(ྫ֎ ) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
  9. 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ϦΫΤετͯ͠ಘΒΕͨ ಺༰Λฦ͢
  10. ܖ໿ʹΑΔઃܭ (Design by Contract) ❖ ࣄલ৚݅ͱࣄޙ৚݅ͱ͍͏એݴతͳੑ࣭ʹج͍ͮͯ
 ؔ਺Λઃܭ͢Δ ❖ ؔ਺ͱͦͷར༻ऀͷؒʹ͸ˢͷΑ͏ͳܖ໿͕͋Δͱ
 ଊ͑Δ

    ʮ΋ͦͪ͠Β͕ࣄલ৚݅Λຬͨͨ͠ঢ়ଶͰࢲΛ ݺͿͱ໿ଋͯ͠Լ͞ΔͳΒ͹ɺ
 ͓ฦ͠ʹࣄޙ৚݅Λຬͨ͢ঢ়ଶΛ࠷ऴతʹ࣮ݱ ͢Δ͜ͱΛ͓໿ଋ͠·͢ʯ
  11. 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ϦΫΤετͯ͠ಘΒΕͨ ಺༰Λฦ͢ Τϥʔͷ಺༰ʹԠͯ͡
 ॲཧΛ੾Γସ͍͑ͨ
  12. 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ϦΫΤετͯ͠ ੒ޭ͢Ε͹ಘΒΕͨ಺༰Λฦ͢/ࣦഊ͢Ε͹ΤϥʔͷछྨΛฦ͢
  13. 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ϦΫΤετͯ͠ ੒ޭ͢Ε͹ಘΒΕͨ಺༰Λฦ͢/ࣦഊ͢Ε͹ΤϥʔͷछྨΛฦ͢
  14. ཁٻܕͷؔ਺ͱอޢܕͷؔ਺ ❖ ཁٻܕͷؔ਺ • ݺͼग़͠ଆ͕ࣄલ৚݅Λຬͨ͢͜ͱΛཁٻ͢Δؔ਺ • ex. ͢΂ͯͷ৔ॴͰྫ֎Λ࢖͍ͬͯͨύλʔϯ ❖ อޢܕͷؔ਺

    • ͲΜͳೖྗͰ΋ͳΜͱͯ͠ॲཧ͢Δؔ਺ • ex. Ұ൪৚݅ΛΏΔΊͨύλʔϯ ͲͪΒ͕ྑ͍͔͸ɺ࣌ͱ৔߹ɺ޷ΈʹΑΔ
  15. 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); } Ҿ਺Λ౉͠Θ͢Εͯͯ΋ಈ͘ อޢܕͷؔ਺ͷ৔߹ ຊ࣭తͰͳ͍ॲཧ͕૿͑Δ ೖྗ஋ݕࠪͷ੹೚͕ᐆດʹ
  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; } ཁٻܕͷؔ਺ͷ৔߹ ෆਖ਼ͳݺͼग़͠͸Τϥʔ ࢓༷ʹԊ͏ݕࠪͷΈΛߦ͏ ೖྗ஋ݕࠪͷ੹೚͸ݺͼग़͠ଆ
  17. my $input_token = <STDIN>; if (!$input_token) { print "Please input

    token"; exit 1; } my $content = retrieve_content_by_token_die($token); ࣄલ৚݅ΛνΣοΫͯ͠ݺͼग़͢ ࣄલ৚݅Λຬͨ͢͜ͱͷνΣοΫ ҆৺ͯ͠ݺͼग़͢ Ϟσϧͷ
 ϩδοΫ Ϣʔβೖྗ ϑΟϧλ
  18. ϨΠϠͷ͋ΔΞʔΩςΫνϟͷ৔߹ Ϣʔβೖྗ • ೖྗͷνΣοΫ • νΣοΫOK
 → ϩδοΫݺͿ • νΣοΫNG


    → ΤϥʔΛฦ͢ • ೖྗΛ৴པͯ͠
 υϝΠϯϩδοΫ
 Λ࣮ߦ อޢܕͷϝιου ཁٻܕͷϝιου ΠϯλʔϑΣʔε υϝΠϯϩδοΫ ݺͼग़͠ ϨΠϠͷ੹೚ʹରԠ͢Δ