Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
極める!メソッドチェーン #phpstudy / fluent-interface
Search
Hiraku NAKANO
July 26, 2017
Technology
3.1k
8
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
極める!メソッドチェーン #phpstudy / fluent-interface
2017/07/26 第116回 PHP勉強会の発表資料です。
Hiraku NAKANO
July 26, 2017
More Decks by Hiraku NAKANO
See All by Hiraku NAKANO
iD決済を支える技術 / #merpay_techtalk
hirak
33
7.3k
github.com/mercari の今と昔 /github-mercari
hirak
8
3.2k
PHPStanで始める継続的静的解析 #phperkaigi /php-static-analysis
hirak
14
55k
evalこそパワー #phpkansai / phpkansai2017
hirak
2
1.8k
PHPのエラーと例外再入門 / php-error-and-exception
hirak
19
20k
メルカリ JP Tech Side / mercari-jp-tech-side
hirak
7
2.1k
グローバル展開を支える量子的なサービス設計 #mercariday / mercariday2017-api
hirak
22
14k
Composerプラグインを作ってみよう /phpcon2016
hirak
5
14k
packagist.jpの紹介と新機能 /#phpblt
hirak
4
3k
Other Decks in Technology
See All in Technology
ビジネス部門からPOを迎えての半年間の進歩と課題
zozotech
PRO
0
150
What Is JetBrains Air
x5gtrn
PRO
0
170
Vue.jsのGitHubから学ぶ意思決定
yut0naga1_fa
1
280
LLM Content Moderationを支える評価・改善ループの実践
suikabar
2
360
AI時代、つくる力を自分たちの手に。 ──電通×KAG、アジャイルとAI駆動開発で挑む開発の変革
yuukiyo
3
390
Let's Change Our World—Again
snoozer05
PRO
6
680
企画を Software Factory-ready にする——開発が高速になったとき、PdMの仕事はどう変わったか
yachibit
1
270
外国人エンジニアがVueプロトタイプで仕様を合わせている話 / Vue Fes Japan 2026 LT
eluwing
0
170
Autonomous AI Lakehouse - Live AI Hubから始めるセキュアなAIデータ活用 -
oracle4engineer
PRO
2
150
AI駆動開発におけるハーネスエンジニアリングの勘所
tsukuboshi
1
790
AWS DevOps Agentはどこまで任せられるか 〜機能の現在地と、機能拡張の実践〜
nyankotaro
0
250
AWSDirectConnectの構築の進め方を整理してみた
masa_my
1
200
Featured
See All Featured
GitHub's CSS Performance
jonrohan
1033
470k
Typedesign – Prime Four
hannesfritz
42
3.2k
Git: the NoSQL Database
bkeepers
PRO
433
67k
Documentation Writing (for coders)
carmenintech
77
5.6k
Done Done
chrislema
187
17k
Building Better People: How to give real-time feedback that sticks.
wjessup
371
20k
Amusing Abliteration
ianozsvald
1
360
So, you think you're a good person
axbom
PRO
2
2.2k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1.4k
Fantastic passwords and where to find them - at NoRuKo
philnash
53
4k
Beyond borders and beyond the search box: How to win the global "messy middle" with AI-driven SEO
davidcarrasco
3
280
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.6k
Transcript
ۃΊΔʂ ϝιουνΣʔϯ @hiraku
ࣗݾհ • த (@Hiraku) • https://github.com/hirak • ϝϧΧϦͷαʔόʔαΠυΤϯδχΞ •
Composerؔ࿈ͷൃදΛΑ͍ͯ͘͠·͢ • PHPΧϯϑΝϨϯεؔ2016 جௐߨԋ
We are hiring!
None
None
None
ۃΊΔʂ ϝιουνΣʔϯ @hiraku
ϝιουνΣʔϯͱ $talk ->setTitle('art of method chain') ->setContent('no plan') ->setLength('20min') ;
ΦϒδΣΫτʹରͯ͠ɺ ϝιουΛଓ͚ͯॻ͚ΔΑ͏ʹ ͨ͠ύλʔϯ/APIσβΠϯͷ͜ͱ
5લʹൃදͨͭ͠ https://www.slideshare.net/hinakano/xml-builder
None
ͪΖΜ߹๏ͳPHPߏจ
Χοίলུ&Մมϝιου໊ ด͡λά͕ͳ͍͜ͱͷ໌ࣔ ด͡λάิ
࠷ۙॻ͍ͨͭ PHPͷߴΦγϟϨةݥྻϥΠϒϥϦspindle/collectionΛ࡞͍ͬͯΔ - Qiita http://qiita.com/Hiraku/items/bb6318d1d2c26ae7f30a
·ΔͰͯ͠ͳ͍…
ϝιουνΣʔϯେ͖ • ੍ͰPHPΒ͘͠ͳ͍ߏจΛ࡞Δઓ • PHPߏจ͕ශऑͩͬͨ • ݺͼग़͠νΣʔϯͰ͖ͳ͍ͱ͔()()()() • །Ұੲ͔Β͑ͨͷ͕ϝιουνΣʔϯ
͓͜ͱΘΓ • ϥΠϒϥϦΛఏڙ͢ΔਓԿΛߟ͑Δ͖͔ʁ Έ͍ͨͳΛ͠·͢ • ҰੲલͷJavaͷম͖͔͠͠Εͳ͍
࣍ 1. σϝςϧͷ๏ଇ 2. ϝιουνΣʔϯͷύλʔϯ৭ʑ 3. APIσβΠϯͷ͓ 4. σϞతͳͭ
1ষ σϝςϧͷ๏ଇ ۃΊΔ!ϝιουνΣʔϯ
σϝςϧͷ๏ଇ (࠷খࣝͷݪଇ) (Law of Demeter, LoD) • ιϑτΣΞͷઃܭɺಛʹΦϒδΣΫτࢦ ϓϩάϥϜͷઃܭʹ͓͚ΔΨΠυϥΠϯ •
ʮ๏ଇʯͱ͍͏༁͕ͩɺʮ͜ΕΛकͬͯΔ ίʔυͷํ͕͍͍Αʂʯͱ͍͏Α͏ͳओࢫ
σϝςϧOK? 0, /( B BCD UIJTB UIJTB C UIJTBC UIJTBC
D
৮ͬͯྑ͍ͷ 0, ϩʔΧϧมɺҾ৮ͬͯ0, B ࣗͷϝιου৮ͬͯ0, UIJTB ࣗͷϓϩύςΟͷϝιου ৮ͬͯ0, UIJTBC
$talk ->setTitle('art of method chain') ->setContent('no plan') ->setLength('20min') ; $talk->setTitle('art
of method chain'); $talk->setContent('no plan'); $talk->setLength('20min'); LoDकͬͨํ͕͍͍ͷʁ ϝιουͷΓ is Կʁ ͜ΕͳΒΓΛؾʹ͢Δ·Ͱͳ͍
ϝιουνΣʔϯͱ $talk ->setTitle('art of method chain') ->setContent('no plan') ->setLength('20min') ;
ΦϒδΣΫτʹରͯ͠ɺ ϝιουΛଓ͚ͯॻ͚ΔΑ͏ʹ ͨ͠ύλʔϯ/APIσβΠϯͷ͜ͱ
͍
ϝιουνΣʔϯLoDҧ • LoDతʹɺ$this->set...; $this->set...; ͱͦΕ ͧΕॻ͖͘ • LoDɺϥΠϒϥϦઃܭऀ͕͓͖ͬͯ͘ ݪଇͷ̍ͭͰ͋Δ
Ұ୴ɺLoDஔ͍ͱ͍ͯɺ ΛਐΊ·͢ɻ
2ষ ϝιουνΣʔϯͷ ύλʔϯ ۃΊΔ!ϝιουνΣʔϯ
LoDΛഁͬͯ·Ͱ ϝιουνΣʔϯͰ ԿΛ͍ͨ͠ͷ͔ʁ
1) return $this class Chainable { function setA($val) { $this->a
= $val; return $this; } function setB($val) { $this->b = $val; return $this; } } (new Chainable) ->setA('a') ->setB('b'); ࿈ଓͰsetͰ͖ΔΑ͏ʹͳͬͨΑʂ
return $this ʹର͢Δݸਓతཧղ • $instance->ͬͯॻ͔ͳͯ͘Α͘ͳΔ • ͪΐͬͱ͚ͩShort hand • ͨͩͦΕ͚ͩͳͷͰɺLoDഁΔ΄ͲͷՁ͕
͋Δ͔…ͱ͍͏ͱඍົͳؾ͢Δ
2) PSR-7ͷAPIΈ͍ͨͳͭ (new GuzzleHttp\Psr7\Request('GET', 'http://example.com')) ->withHeader('foo', 'baa') ->withBody($body); return $thisͰͳ͘ɺ
newͯ͠ࠓ·ͰͷใΛίϐʔ (ผΠϯελϯεΛฦ͢)
immutableͱ • setterͷͳ͍ΦϒδΣΫτ • ෦ΛมߋͰ͖ͳ͍ͷͰɺ clone͠ͳͯ҆͘શʹฦͤΔ • setterͰͳ͘ɺʮίϐʔͯ͠Ұ෦Λ্ॻ͖ʯ ͢ΔσβΠϯ
immutable ʹର͢Δݸਓతཧղ • ΓΛड͚औΒͳ͍ͱ݁Ռ͕ফ͑ͯ͠·͏ • $obj->setFoo($foo); $obj->setBaa($baa); ͯ͠ҙຯ͕ͳ͍ • $obj
= $obj->setFoo($foo); $obj = $obj->setBaa($baa); • ه๏͕໘ͳͷͰɺϝιουνΣʔϯʹͨ͘͠ͳΔ(Θ͔Δ)
ͪΐͬͱ͕ҳΕ·͕ͨ͠ • return $this͢Δ͚͕ͩϝιουνΣʔϯͰ ͳ͍ • return new ͢Δύλʔϯ͋Δ
return newͰ ༡ΜͰΈΔྫ
͓ • ϝιουνΣʔϯͰ ೖΕࢠͰ͖ΔifจΛ ࡞Ε
ϒϩοΫʹΦϒδΣΫτΛͯ ΊΔ • ifnewΛฦ͢ • endifϒϩοΫΛ ऴΘΒͤͯͱʹ Δ
<?php abstract class Context { protected $parent = null; function
__construct(Context $parent=null) { $this->parent = $parent; } abstract function if(bool $bool): Context; abstract function say(string $str): Context; function endif(): Context { return $this->parent; } } class TrueContext extends Context { function if(bool $bool): Context { if ($bool) { return new self($this); } else { return new FalseContext($this); } } function say(string $str): Context { echo $str,PHP_EOL; return $this; } } class FalseContext extends Context { function if(bool $bool): Context { return new self($this); } function say(string $str): Context { return $this; } } function dsl(): TrueContext { return new TrueContext; } ͍͍ͩͨ ͜Ε͙Β͍ Ͱ࡞ΕΔ ϝιουνΣʔϯDSLͰϒϩοΫΛ࡞ΔςΫχοΫ: Architect Note http://blog.tojiru.net/article/272060766.html
3) +ϚδοΫϝιουͷཚ༻ return $thisͰͳ͘ɺ newͯ͠ࠓ·ͰͷใΛίϐʔ (ผΠϯελϯεΛฦ͢)
ϚδοΫϝιου • __get(){}ɺ__call(){}ΛΫϥεʹੜ͓ͯ͘͠ • ϓϩύςΟ/ϝιουʹΞΫηεग़དྷͳ͍ͱ͖ ʹࣗಈతʹݺΕΔ • Rubyͷmethod_missingΈ͍ͨͳͭ
IUNM NFUB@ UJUMF@ @ ͳΜͯϝιου QVCMJDϓϩύςΟੜ͍͑ͯͳ͍ɻ ࣮ࡍʹॲཧ͍ͯ͠Δͷ @@DBMM ͱ@@HFU
ϚδοΫϝιου • ✅ίʔυྔ(ܶతʹݮΔ) • ❌ಡΈ͢͞ • ❌֦ுੑ • ❌PhpStormʹౖΒΕΔ •
ׂͱݏ͍ͬͯΔPHPer͕ଟ͍ҹ(ओ؍)
4) fluent interface • ʮྲྀΕΔΑ͏ͳΠϯλʔϑΣʔεʯ • ϝιουνΣʔϯΛ͏গ͠ൃలͤͨ͞ͷ • આ໌͕͍͠ͷͰ࣍ͷষ
3ষ APIσβΠϯͷ ۃΊΔ!ϝιουνΣʔϯ
ঢ়گ • ͋ͳͨɺͱ͋ΔWebαʔϏεͷPHP൛SDK Λ࡞Δ͜ͱʹͳΓ·ͨ͠ • ͦͷWebαʔϏεେྔͷػೳ͕͋Γ·͢ɻ • SDKͳͷͰɺੜcurlͰୟ͘ΑΓศརʹ͍ͨ͠
None
None
SDKͷAPIσβΠϯ • SDKϢʔβʔ෦࣮ΛΑ͘Βͳ͍ • Ͱ͖ΕυΩϡϝϯτ͚ͩͰ͍͜ͳ͍ͨ͠ • ͲΜͳΫϥε͕͋ͬͯɺ ͲΜͳϝιουΛஔ͢Δʁ
…Ԟͷਂ͍Ͱ͋Δ
ςϨϏͷϦϞίϯ
None
Α͋͘ΔςϨϏͷϦϞίϯ • Ϙλϯ͕͍ͬͺ͍͋Δ • ͲΕΛԡ͍͍ͤͷʁ໎͏ • (ͨͿΜ)ςετେมͦ͏… • ͍ͭͰ͋ΒΏΔϘλϯ͕ԡͤΔ
ղܾҊ • ͍͞͠ΐϘλϯ1ݸ(ిݯ)ͷΈ • ిݯ͕ೖΔͱɺ͏ʹΐʔΜͱϘλϯ͕ੜ͑ͯ͘Δ • ૢ࡞͢ΔͨͼʹɺϘλϯ͕͏ʹΐʔΜͱੜ͑ͯ͘ Δ or ফ͑Δ
• ϘλϯݮΒͤͦ͏Ͱ͢Ͷʂ
API = ϦϞίϯ
APIσβΠϯʹͯΊͯΈΔ • ϩάΠϯ͕ඞཁͳΒɺϩάΠϯͷAPI͚͕ͩ ݟ͑ͯΔ͖ • ͦͷঢ়ଶͰՄೳͳૢ࡞͚͕ͩ͑Δ • linkͰػೳΛͭͳ͙RESTͷΑ͏ͳߟ͑ํ
fluent interfaceͷߟ͑ํ • จ຺(ίϯςΩετ)ʹԠͯ͡ɺreturn͢Δ ΫϥεΛมߋ͢Δ • ඞཁेͳϝιου͚ͩ৮ΕΔঢ়ଶΛอͭ
4ষ SELECTจϏϧμʔ ۃΊΔ!ϝιουνΣʔϯ
ΫΤϦϏϧμͬͯ͋Γ·͢ΑͶ • PHP্ͰSQLΛΈཱͯΔͭ • ΞϨΛfluent interfaceͰઃܭ(design)ͯ͠ Έ·͠ΐ͏ • ࣮·Ͱؒʹ߹Θͳ͔ͬͨ
SELECTจͷ෮श ͍͍ͩͨҎԼͷॱͰॲཧ͞ΕΔ FROM → JOIN → WHERE → GROUP BY
→ HAVING → PROJECT → ORDER BY → LIMIT → UNION ࢦఆॱΛ͜ΕͰݻఆͰ͖ΔΑ͏ʹAPIઃܭ
ࡉ͔͘ΫϥεΛ༻ҙ
ΓΛ࣍ͷίϯςΩετʹ
ͱ͍͏Θ͚Ͱదʹ࡞ͬͨͭ https://github.com/hirak/php-query-builder (APIσβΠϯͷͳͷͰதϞοΫঢ়ଶ)
Demo
fluent interfaceͷ͍͍ͱ͜Ζ • IDEͷิͱΈ߹ΘͤΔͱޮՌ͙ͭΜͩ
APIઃܭऀͷ಄ͷத • LoDʹै۪ͬͨͳઃܭʹ͢Δ͖͔ʁ • ίϯςΩετΛಋೖͯ͠fluent͗Έʹ͢Δ͔ʁ • ΞϓϦͷUIΛߟ͑Δ͜ͱͱࣅ͍ͯΔ • ਖ਼ղͳ͍͚Ͳɺ͍Ζ͍ΖͳྲྀΛ͓ͬͯ ͘ͱɺཱ͍͔͔ͭͭʁ
·ͱΊ
Ԟਂ͖ϝιουνΣʔϯͷੈք • σϝςϧͷ๏ଇ͓͖֮͑ͯ·͠ΐ͏ • ϝιουνΣʔϯͰDSLͬΆ͍ͷ࡞Δͱ ָ͍͠Α • return $thisҎ֎ʹ৭ʑ͋Δͷ͓֮͑ͯ͘ ͱ͍͍Α
ͦͷଞͷ
Unified Variable Syntax (PHP7) • PHP7͔ΒɺνΣʔϯͰ͖ΔߏจͷόϦΤʔ γϣϯ͕૿͑ͯΔ • abc()()ɺBaa::a()::foo() •
Կ͔͍ํͳ͍͔ͳʔɻɻ