Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Speaker Deck
PRO
Sign in
Sign up for free
契約による設計の紹介
hakobe (Yohei Fushii)
August 25, 2016
Programming
6
19k
契約による設計の紹介
hakobe (Yohei Fushii)
August 25, 2016
Tweet
Share
More Decks by hakobe (Yohei Fushii)
See All by hakobe (Yohei Fushii)
はてなにおけるプログラミング言語の歴史とこれから
hakobe
0
350
ざっとわかるPython
hakobe
4
6.5k
はてなで一人前のエンジニアになる方法
hakobe
4
6.2k
アクターによる 並行処理アプケーション アーキテクチャ
hakobe
4
3k
Scala In Perl Company
hakobe
11
11k
TDDの練習 Coding Kata の実践
hakobe
0
1.2k
なめらかにGHEに移行する方法
hakobe
19
7.3k
開発フロー@はてなブックマーク
hakobe
0
110
Git on WebApp with Perl
hakobe
1
3.5k
Other Decks in Programming
See All in Programming
Edge Side Frontend という新領域
mizchi
22
10k
20220706_Google Apps Scriptを実演で学ぶ~ GAS × Slack ~
apachan
2
620
モデルの定義に基づくバリデーションを実現するためのpydantic入門
daikikatsuragawa
0
120
段階的な技術的負債の解消方法.pdf
ko2ic
2
920
Dagger, la CI, autrement
guikingone
1
110
このタイミングで知っておきたい 開発生産性の高いエンジニア組織の特徴とは / dev-sumi-20220721-productivity-features
findyinc
7
2.6k
回帰分析ではlm()ではなくestimatr::lm_robust()を使おう / TokyoR100
dropout009
0
4.5k
ESM移行は無理だけどおれもSindreのライブラリが使いたい!
sosukesuzuki
2
550
Git操作編
smt7174
2
240
僕が便利だと感じる Snow Monkey の特徴/20220723_Gifu_WordPress_Meetup
oleindesign
0
110
話題の AlloyDB は本当に凄いデータベースなのでプレビューを使い倒した #devio2022
maroon1st
0
13k
테라폼으로 ECR 관리하기 (How to Manage ECR with Terraform)
posquit0
0
520
Featured
See All Featured
Thoughts on Productivity
jonyablonski
44
2.4k
Bash Introduction
62gerente
598
210k
Creatively Recalculating Your Daily Design Routine
revolveconf
207
10k
Teambox: Starting and Learning
jrom
123
7.7k
CSS Pre-Processors: Stylus, Less & Sass
bermonpainter
349
27k
How STYLIGHT went responsive
nonsquared
85
4k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
269
12k
For a Future-Friendly Web
brad_frost
166
7.5k
A better future with KSS
kneath
226
16k
Templates, Plugins, & Blocks: Oh My! Creating the theme that thinks of everything
marktimemedia
15
980
JavaScript: Past, Present, and Future - NDC Porto 2020
reverentgeek
37
3.3k
Fashionably flexible responsive web design (full day workshop)
malarkey
396
62k
Transcript
ܖʹΑΔઃܭͷհ hakobe932
: ؔͷೖྗग़ྗͷ νΣοΫͲ͏ͯ͠·͔͢?
ؔͷ༷: τʔΫϯΛड͚औΓ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; } ↑ ԿͷΤϥʔνΣοΫͳ͍ ۭจࣈྻͩͬͨΒ ϦΫΤετࣦഊͯͨ͠Β
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 ͬͪ͜ ྑ͘ͳ͍͜ͱ͕ىͬͨ͜Βِ
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ΦϒδΣΫτ ͳΔ͘Ժศʹࡁ·͢ ೖྗ͕͓͔͔ͬͨ͠ΒσϑΥϧτ
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ϦΫΤετͯ͠ •ಘΒΕͨ༰Λฦ͢ ←ਖ਼͍͠ೖྗ͕ಘΒΕͨ࣌ ←Կ͔ࣄΛͯ͠ ←ظ͞ΕΔ݁ՌΛฦ͢
έʔεελσΟʹ͓͚Δؔͷ༷ (Cont. •τʔΫϯΛड͚औΓ •HTTPϦΫΤετͯ͠ •ಘΒΕͨ༰Λฦ͢ ←ࣄલ݅Λຬͨͤ ←Կ͔ࣄΛͯ͠ ←ࣄޙ݅Λຬͨ͢ ؔͷར༻ऀ͕ ؔ
Q: ͕݅͠ຬͨͤͳ͍ͱͲ͏ͳΔ? ❖ ࣄલ͕݅ຬͨͤͳ͍ • ex.τʔΫϯ͕͞Εͳ͔ͬͨ • HTTPϦΫΤετΛ͢ΔͨΊͷURL͕ߏஙͰ͖ͳ͍ ❖ ࣄޙ͕݅ຬͨͤͳ͍
• ex. HTTPϦΫΤετ͕ࣦഊͨ͠ • ฦ͖͢ίϯςϯπ͕࡞Εͳ͍ A: ؔతΛՌͨͤͳ͍ ؔΛ࣮ߦͨ݁͠ՌɺԿ͕ى͜Δ͔ෆఆ
ࣄલ݅ͱࣄޙ݅ͷද໌ ❖ ؔΛਖ਼͘͠ಈ͘ͷʹඞཁͳ݅Λද໌͢Δ # 事前条件: $token は必ず渡される必要がある # 事後条件: 取得したコンテンツは必ず返却される
sub retrieve_content { my ($token) = @_; my $url = 'http://www.example.com/api?token=' . $token; my $res = request($url); return $res->content; }
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) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
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Ͱૉʹྫ֎ʹΑΓදݱ͢Δ͘Β͍͕Ұൠత ίʔυʹΑΔද໌ͷදݱ(ྫ֎ ) τʔΫϯΛ͏͚ͱ͍ͬͯΔ͜ͱͷද໌ ίϯςϯπΛ༻ҙͰ͖ͨ͜ͱͷද໌
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ϦΫΤετͯ͠ಘΒΕͨ ༰Λฦ͢
ܖʹΑΔઃܭ (Design by Contract) ❖ ࣄલ݅ͱࣄޙ݅ͱ͍͏એݴతͳੑ࣭ʹج͍ͮͯ ؔΛઃܭ͢Δ ❖ ؔͱͦͷར༻ऀͷؒʹˢͷΑ͏ͳܖ͕͋Δͱ ଊ͑Δ
ʮͦͪ͠Β͕ࣄલ݅Λຬͨͨ͠ঢ়ଶͰࢲΛ ݺͿͱଋͯ͠Լ͞ΔͳΒɺ ͓ฦ͠ʹࣄޙ݅Λຬͨ͢ঢ়ଶΛ࠷ऴతʹ࣮ݱ ͢Δ͜ͱΛ͓ଋ͠·͢ʯ
ܖʹΑΔઃܭͷར ❖ ਖ਼͍͠ίʔυΛॻ͘ॿ͚ʹͳΔ • ਖ਼͍ؔ͠ͷ͍ํ͕໌֬ʹͳΔ • ·͕͍ͪʹૣ͘ؾ͚ͮΔ • → ιϑτΣΞͷ৴པੑ্͕͢Δ
❖ ؔͷੑ࣭Λੳ͢Δνϟϯε͕ಘΒΕΔ ❖ ؔͷੑ࣭Λදݱ͢ΔυΩϡϝϯτʹͳΔ
Q:ΤϥʔͳΜͰྫ֎ʹ͢Δ? ❖ ͏͢͜͠ৄ͘͠ • ؔͷ༷Λਖ਼͘͠ఆٛ͠Α͏ • ཁٻܕͷؔ/อޢܕͷؔ • ৴པͰ͖ͳ͍ೖྗ༧ΊνΣοΫ͠Α͏ A:
ͦ͏Ͱͳ͍
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ϦΫΤετͯ͠ಘΒΕͨ ༰Λฦ͢ Τϥʔͷ༰ʹԠͯ͡ ॲཧΛΓସ͍͑ͨ
ؔͷ༷Λదʹఆٛ͠Α͏ τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ಘΒΕͨ ༰Λฦ͢ τʔΫϯΛड͚औΓHTTPϦΫΤετͯ͠ ޭ͢ΕಘΒΕͨ༰Λฦ͢ ࣦഊ͢ΕΤϥʔͷछྨΛฦ͢ ؔͱͷదͳܖؔΛߟ͑Δ → ઃܭ
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ϦΫΤετͯ͠ ޭ͢ΕಘΒΕͨ༰Λฦ͢/ࣦഊ͢ΕΤϥʔͷछྨΛฦ͢
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ϦΫΤετͯ͠ ޭ͢ΕಘΒΕͨ༰Λฦ͢/ࣦഊ͢ΕΤϥʔͷछྨΛฦ͢
ཁٻܕͷؔͱอޢܕͷؔ ❖ ཁٻܕͷؔ • ݺͼग़͠ଆ͕ࣄલ݅Λຬͨ͢͜ͱΛཁٻ͢Δؔ • ex. ͯ͢ͷॴͰྫ֎Λ͍ͬͯͨύλʔϯ ❖ อޢܕͷؔ
• ͲΜͳೖྗͰͳΜͱͯ͠ॲཧ͢Δؔ • ex. Ұ൪݅ΛΏΔΊͨύλʔϯ ͲͪΒ͕ྑ͍͔ɺ࣌ͱ߹ɺΈʹΑΔ
ཁٻܕ͕͓͢͢Ί(υϝΠϯϩδοΫͰ) ❖ ͏ଆʹڧ͍݅Λ՝͢͜ͱͰ͕ؔਖ਼͘͠ಈ࡞͢Δ ͜ͱΛڧ੍Ͱ͖Δ ❖ ҟৗͳೖྗΛॲཧ͢Δίʔυ͕ͳ͘ͳΓίΞϩδοΫ ʹूதͨ͠γϯϓϧͳίʔυʹͳΔ ❖ ҟৗͳೖྗΛͲͷΑ͏ʹ੍ޚ͢Δ͔͏ଆͷΈͰ ܾΊΔͷͰͷॴࡏ͕໌Β͔
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); } ҾΛ͠Θ͢Εͯͯಈ͘ อޢܕͷؔͷ߹ ຊ࣭తͰͳ͍ॲཧ͕૿͑Δ ೖྗݕࠪͷ͕ᐆດʹ
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; } ཁٻܕͷؔͷ߹ ෆਖ਼ͳݺͼग़͠Τϥʔ ༷ʹԊ͏ݕࠪͷΈΛߦ͏ ೖྗݕࠪͷݺͼग़͠ଆ
my $input_token = <STDIN>; if (!$input_token) { print "Please input
token"; exit 1; } my $content = retrieve_content_by_token_die($token); ࣄલ݅ΛνΣοΫͯ͠ݺͼग़͢ ࣄલ݅Λຬͨ͢͜ͱͷνΣοΫ ҆৺ͯ͠ݺͼग़͢ Ϟσϧͷ ϩδοΫ Ϣʔβೖྗ ϑΟϧλ
ؔͷ༷Ͳ͏ܾͬͯΊΔͷ͔? ❖ ؔʹͲͷΑ͏ͳΛ༩͑Δͷ͔ ؔͷଐ͢ΔΫϥεϞδϡʔϧʹґଘ͢Δ ❖ ΫϥεϞδϡʔϧͷ ιϑτΣΞͷΞʔΩςΫνϟʹґଘ͢Δ ࡉ෦ͷઃܭશମͷઃܭʹجͮ͘
ϨΠϠͷ͋ΔΞʔΩςΫνϟͷ߹ Ϣʔβೖྗ • ೖྗͷνΣοΫ • νΣοΫOK → ϩδοΫݺͿ • νΣοΫNG
→ ΤϥʔΛฦ͢ • ೖྗΛ৴པͯ͠ υϝΠϯϩδοΫ Λ࣮ߦ อޢܕͷϝιου ཁٻܕͷϝιου ΠϯλʔϑΣʔε υϝΠϯϩδοΫ ݺͼग़͠ ϨΠϠͷʹରԠ͢Δ
ܖʹΑΔઃܭؔʹݶΒͳ͍ ❖ ؔදత͚ͩͲଞͷ෦ʹద༻Ͱ͖Δ • Ϋϥε: ΦϒδΣΫτͷෆม݅ • ϧʔϓ: ϧʔϓෆม݅ ίϯϙʔωϯτͷཁٻΛຬͨ͢͜ͱͰརӹΛಘΔ
ৄ͘͠ΦϒδΣΫτࢦೖΛಡ͏ ❖ ιϑτΣΞઃܭͷຊ ❖ ιϑτΣΞ࣭ͷఆٛ ྺ࢙ΛͨͲֶͬͯΔ ❖ ༗ӹ͚ͩͲྔ͕͓͓͍ • 1800ϖʔδ͘Β͍
• ͕ΜΖ͏
ιϑτΣΞΞʔΩςΫνϟ͕ؾʹͳΔਓ͚ https://8thlight.com/blog/uncle-bob/2012/08/13/the-clean-architecture.html Clean Architecture
·ͱΊ ❖ ʮܖʹΑΔઃܭʯਖ਼͍͠ίʔυͷͨΊͷςΫχοΫ • ؔͷ༷Λࣄલ݅ͱࣄޙ͔݅ΒͳΔܖͱଊ͑Α͏ • ܖʹج͍ͮͯίʔυΛ࣮͠Α͏ ❖ ؔͱͷܖιϑτΣΞΞʔΩςΫνϟΛݩʹ ߟ͑Α͏
• ΫϥεϨΠϠͷΛੳͯ͠ରԠͨ͠Λ༩͑Α͏ • ཁٻܕͱอޢܕΛҙ͍ࣝͯ͠Θ͚Α͏
ޚతϓϩάϥϛϯάͲ͜? ❖ Կ͕ى͜Δ͔Θ͔Βͳ͍ͷͰݸʑͷؔͳΔ͘ ͋ΒΏΔೖྗνΣοΫ ❖ ؔͷఆٛͱݺͼग़͠ܖͱ͍͏ܗͰཧ͞Ε͍ͯ Εγϯϓϧͳίʔυͱ໌͕֬͞ҡ࣋͞ΕΔ