Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
フレームワークを作らない方法/How NOT to build frameworks
Search
MOROHASHI Kyosuke
June 21, 2019
Programming
1.3k
4
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
フレームワークを作らない方法/How NOT to build frameworks
銀座Rails#10での発表資料です
MOROHASHI Kyosuke
June 21, 2019
More Decks by MOROHASHI Kyosuke
See All by MOROHASHI Kyosuke
Railsの気持ちを考えながらコントローラとビューを整頓する/tidying-rails-controllers-and-views-as-rails-think
moro
5
510
dynamic!
moro
11
21k
Identifying User Idenity
moro
23
29k
Simplicity on Rails -- RDB, REST and Ruby
moro
18
21k
ちょうどよい Rails E2E テスト/enough-good-rails-e2e-test
moro
6
2.7k
全体がいい感じになるために、私たちRailsをホームにするWeb技術者ができること/let-our-whole-system-grow
moro
2
2k
フォームオブジェクトとの向き合い方/Grow Form Objects up
moro
1
2.2k
チームによるいきいきとしたソフトウェア開発/an-alive-team-grows-software
moro
3
3.5k
Web-E2E-Testing-from-Ruby
moro
5
660
Other Decks in Programming
See All in Programming
信頼性について考えてみる(SRE NEXT 2026 miniLT)
hayama17
0
190
LLMによるContent Moderationの本番運用の裏側と品質担保への挑戦
suikabar
3
850
【やさしく解説 設計編・中級 #1】一つの車に、運転手は一人 ~ある倉庫システムの事例から~
panda728
PRO
0
180
霧の中の代数的エフェクト
funnyycat
1
390
【やさしく解説 設計編 #1】「ドメイン駆動」と「実装駆動」ってなに? 〜設計の考え方を、たとえ話で学ぼう〜
panda728
PRO
1
120
Welcome to the "Parametricity" 🏙️ − Generic だけど Specific な世界 −
guvalif
PRO
1
170
Laravelで学ぶ Webアプリケーションチューニング入門/web_application_tuning_101
hanhan1978
4
560
ITヒヤリハットを整理してみた ~ライフサイクルと原因から考える再発防止策~
koukimiura
1
100
使用 Meilisearch 建立新聞搜尋工具
johnroyer
0
150
Apache Hive: Toward a Cloud Native Lakehouse
okumin
0
130
えっ!!コードを読まずに開発を!?
hananouchi
0
210
JAWS-UG横浜 #102 AWSサ終供養LT会 成仏できない AWS サービスたち 〜本日、三体供養します〜
maroon1st
0
200
Featured
See All Featured
The Invisible Side of Design
smashingmag
301
52k
The World Runs on Bad Software
bkeepers
PRO
72
12k
Why Our Code Smells
bkeepers
PRO
340
58k
Amusing Abliteration
ianozsvald
1
230
Documentation Writing (for coders)
carmenintech
77
5.4k
Done Done
chrislema
186
16k
Facilitating Awesome Meetings
lara
57
7k
Agile Actions for Facilitating Distributed Teams - ADO2019
mkilby
0
220
4 Signs Your Business is Dying
shpigford
187
22k
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
45k
Redefining SEO in the New Era of Traffic Generation
szymonslowik
1
360
The MySQL Ecosystem @ GitHub 2015
samlambert
251
13k
Transcript
ϑϨʔϜϫʔΫΛ ࡞Βͳ͍ํ๏ )PX/05UPCVJMEGSBNFXPSLT 2019-06-21 ۜ࠲Rails#10 ॾڮګհ @moro
‣ ࣸਅ
Kyosuke MOROHASHI @moro
!5 SMS? What's SMSってなにをやってる会社なの?
https://twitter.com/sunaot/status/1002392476492038144
“ 情報インフラを構築することで、⾼齢社会を 取り巻く⼈びと、⾼齢社会で働く⽅や事業者の⽅、 ⾼齢者ご⾃⾝やそのご家族などがイキイキと ⽣活できる社会の実現を⽬指しています。 — https://www.bm-sms.co.jp/philosophy/
!8 &
吳䒭⠓爡ؒأ ٥ ؒي ٥ ؒأ 匌❨鿪庥⼒蓎Ⱅ㕦⡝♶⹛欵蓎Ⱅ㕦ةٙ٦ https://www.bm-sms.co.jp ؒٝآص،䱰欽؟؎ ز https://careers.bm-sms.co.jp/engineer/
join us!
͜Ε·Ͱͷ͋Β͢͡
‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚͚Δ
‣ ·ͱΊ੍ޚߏΛ͍खʹҕͶΔ
ͳͥ ϑϨʔϜϫʔΫʹ͠ͳ͍ ΄͏͕Α͍͔
ϥΠϒϥϦͱ ϑϨʔϜϫʔΫ
“ ͔͠͠ɺϥΠϒϥϦͰݺͼग़͠ଆ͕ϓϩάϥϜશ ମͷ੍ޚߏΛࢦఆͰ͖ͳ͍͕ɺϑϨʔϜϫʔΫͰ ՄೳͰ͋Δɻ͜ͷ੍ޚͷస͕ιϑτΣΞϑ ϨʔϜϫʔΫͷಛͰ͋Δɻ https://ja.wikipedia.org/wiki/ιϑτΣΞϑϨʔϜϫʔΫ
‣ ʮར༻ऀ͕ݺͼग़͢ʯͷ͕ϥΠϒϥϦ ‣ ʮར༻ऀ ͷίʔυ Λݺͼग़͢ʯͷ͕ϑϨʔϜϫʔΫ ϑϨʔϜϫʔΫ੍ޚߏΛࢦఆ͢Δ
‣ ͖ͬΓͱനࠇ͚ͭΒΕΔΘ͚Ͱͳ͍ɻ ‣ ར༻ऀͨΔΞϓϦ։ൃऀ͕ݺͼग़͢"DUJWF3FDPSE Ϟσϧʹఆٛͨ͠ίʔϧόοΫ"DUJWF3FDPSE͕ݺͼग़ͧ͢ʜ ‣ ར༻ऀ͕ॻ͘ίʔυͷ੍ޚߏΛͲΕ΄Ͳࢦఆ ͢Δ͔͠ͳ͍͔ɻ ˞۠ผ߹͍
‣ ϑϨʔϜϫʔΫɺͦͷ্Ͱͷ׆ಈΛ੍͢Δɻ ‣ ͍ΘΏΔʮϨʔϧ͔Β߱Γ͍ͨʯ ‣ ඞͣ͠ѱ͍Θ͚Ͱͳ͍ʮ੍͕ࣗ༝ΛͨΒ͢ʯ ‣ ʮͦͷ্Ͱͷ׆ಈʯ༧ଌͰ͖ͳ͍ɻ ‣ ͍͍ͨͯநԽ͕࿙ΕΔɻ
‣ ࡞ऀͷؾ࣋ͪΛߟ͑Α͏ͱͯ͠࡞ऀߟ͑ͯͳ͍͜ͱɻ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕ྑ͍͔
‣ ಡΈղ͘ͷʹϝλϓϩάϥϛϯάͷ͕ࣝඞཁʹͳΔ͜ͱଟ͍ɻ ‣ ϝλϓϩάϥϛϯάֶशۂઢ ίʔυࣗମ͕͘͠ͳΓ͕ͪ https://www.martinfowler.com/articles/rubyAtThoughtWorks.html
‣ ଟ͘ͷ"1*ͱͦͷ͍ํΛֶश͢Δඞཁ͋Γɻ ‣ ࡞ऀͷؾ࣋ͪΛߟ͑ͯΞϓϦέʔγϣϯίʔυ Λॻ͘ɻ ϑϨʔϜϫʔΫࣗମֶशίετ͕͔͔Δ
‣ 3VCZͰ8FCΞϓϦ։ൃ͢Δͱ͖ͷυఆ൪ͱͯ͠ ϝΠϯετϦʔϜʹ͍Δɻ ‣ ৭Μͳ༻్ͷʮݸผࣄʯΛίϯτϦϏϡʔτ͞Ε ଓ͚͖ͯͨɻ ‣ ʮϨʔϧͷ߱ΓํʯͳΜͯͷ·ͰؚΊͯେͳ ϊϋ͕ੵ͞Ε͍ͯΔɻ
3BJMTϛϥΫϧ
‣ ࣗࣗΛؚΉ ະདྷͷϝϯςφʹର੍͠͠ͳ͍ɻ ‣ ະདྷʹͲ͏͍͏ιϑτΣΞʹ͍͔ͨ͠Θ͔Βͳ͍ɻ ‣ େମʹ͓͍ͯߟྀෆ͠நԽ࿙ΕΔɻ ‣ ϥΠϒϥϦʹ͓ͯ͘͠ͱɺݺͿݺͳ͍ɺ ͏ݺͳ͘͢Δɺͷར༻ऀ͕ܾΊΒΕΔɻ
ʮ;ͩΜʯϑϨʔϜϫʔΫʹ͢ΔͷΛආ͚Δ
ͱ͍͑ɺ ศརϝιουΛॻ͖ͨ͘ͳΔ͜ͱ ͨ͘͞Μ͋ΔΘ͚Ͱ
‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚͚Δ
‣ ·ͱΊ੍ޚߏΛ͍खʹҕͶΔ
ϑϨʔϜϫʔΫΛ ࡞Βͳ͍ํ๏
ݴ͍͑Δͱ ੍ޚߏΛ ͍खʹҕͶΔํ๏
ςϯϓϨʔτϝιουΛආ͚ͯ ;ͭ͏ʹϝιουʹநग़͢Δ
‣ ΦʔόʔϥΠυ͞ΕͯΔϝιουΛΈଆ͕ݺͿɻ ݺΕΔଆ͔Βߏ͕ݟ͑ͳ͍ɻ ‣ 34QFDͷMFUTVCKFDUಉࠜͰ͋Δͱݴ͑Δɻ ‣ ۩ςετέʔε͔ΒΕͨʮϑΝΠϧͷ্ͷํʯʹ ߏ͕Ͱ͖ΔͷͰɺݟ͑ͳ͍͠ɺม͑ͮΒ͍ɻ ςϯϓϨʔτϝιουύλʔϯͷ
‣ ܧঝͯ͠͠·͏ͷͰɺϑϨʔϜϫʔΫͷ෦ߏΛ ࡽͯ͠͠·͏ɻ ‣ ͞ΘΓͨ͘ͳΔΑͶ ‣ ͦͯ͠όʔδϣϯΞοϓͰ͖ͳ͘ͳΔ ‣ 3BJMTΞϓϦ͋Δ͋Δɻ ςϯϓϨʔτϝιουύλʔϯͷ
‣ 3BJMTࣗମ͕ϥΠϒϥϦఏڙΫϥεΛܧঝͯ͠͏ ϑϨʔϜϫʔΫͳͷͰɺࣗͰͦ͏ॻ͖ͨ͘ͳΔɻ ‣ ʜΑͶ ‣ 999#BTF͍ͬͯ͏நΫϥεΛఆٛͨ͜͠ͱ͋Δਓ ‣ 3BJMT͔ͩΒͰ͖Δ͜ͱɻ
3BJMTϛϥΫϧ
ϝιουʹநग़͠ɺࣗͰݺͼग़͢
‣ Ұ࿈ͷΦϒδΣΫτάϥϑΛ࡞Δϝιο υʹநग़͠ɺ࡞Γ͍ͨଆ͕ݺͼग़͢ɻ ‣ ࠩΛҾͰ༩͑ͭͭɺ ‣ ΊͬͪΌී௨ͷ͜ͱΛݴͬͯ·͢ ϝιουʹநग़͠ɺࣗͰݺͼग़͢
let!(:article) { create(:article, author: author } # ...͜ͷؒ
30ߦ... context ';ͭ͏ͷϢʔβʔͷهࣄҰཡදࣔର' do let(:author) { create(:author) } it { expect(Article.indexable).to include(article) } context 'ୀձͨ͠ϢʔβʔͷهࣄҰཡදࣔର֎' do let(:author) { create(:author, retired_at: Time.now) } it { expect(Article.indexable).not_to include(article) }
def article_by(user) create(:article, author: author) end context ';ͭ͏ͷϢʔβʔ'
do let(:article) { article_by(create(:user)) } it { expect(Article.indexable).to include(article) } context 'ୀձͨ͠Ϣʔβʔ' do let(:article) { article_by(:author, retired_at: Time.now) } it { expect(Article.indexable).not_to include(article) }
‣ BVUIPSVTFS͕Ͳ͏࡞ΒΕͲ͏ΘΕΔ͔ɺॱΛͬ ͯಡΊΔɻ ‣ ϔϧύʔϝιου͕େ͖͘ͳΔଟ͘ͳΓ͗͢Δ ଞͷϑΝΠϧ͔Β͍͍ͨ߹ɺී௨ʹ ίʔυΛׂ͢ΔͱΑ͍ɻ ‣ কདྷɺςετίʔυΛॻ͘ਓ͕ɺ͍ํΛࣗͰ ܾΊΒΕΔɻ
ҧ͏ॲཧΛڬΈࠐΉͨΊʹ ετϥςδʔύλʔϯΛ͏
‣ ڞ௨ͷલॲཧΛͯ͠ɺຊॲཧͯ͠ɺڞ௨ͷޙॲཧ͕ ͋Δ߹ͳͲɻ ‣ ͞Βʹຊॲཧͷྫ֎ॲཧඞཁͳ߹ͳΜ͔ʹͳΓ͕ͪɻ ‣ ͜ͷຊॲཧ͚ͩΛม͍͑ͨɻ ‣ ςϯϓϨʔτϝιου͍ͨ͘ͳΓ͕ͪɻ ϝιουͷҰ෦͚ͩม͍͑ͨ߹͕͋Δ
class TwitterNotification < BaseNotification private def before_request authorize(@article.author)
def request @user = article.author.access_token ... def after_request nil class BaseNotification def notify(article) @article = article before_request request after_request private def request raise NotImplementedError
ετϥςδʔύλʔϯΛ͏
‣ Ұ෦͚ͩม͍͑ͨॲཧΛɺετϥς δʔΦϒδΣΫτͷೖͰදݱ͢Δɻ ετϥςδʔύλʔϯΛ͏
class TwitterNotification < BaseNotification private def before_request authorize(@article.author)
def request @user = article.author.access_token ... def after_request nil class BaseNotification def notify(article) @article = article before_request request after_request private def request raise NotImplementedError
class SnsNotification def notify(article) #=> [TwitterNotification.new, FacebookNotofication.new...] SnsNotification.targets.each
do |sns| sns.notify(article)
‣ ݺͼग़͢γʔέϯε͕ࣗ໌ʹͳΔɻ ‣ ݺΕΔݸʑͷετϥςδʔଆΠϯλʔϑΣʔε ͕͖ͬΓ͢Δɻ ‣ ৼΔ͍ʹӨڹΛ༩͑Δύϥϝʔλ͕໌֬ʹͳΔͷͰɺςετ͍͢͠ ‣ ݺͼग़͠ݩείʔϓʹΞΫηεͰ͖ͳ͍ ‣
CJOEJOH@PG@DBMMFSͷ͜ͱΕΑ͏
lͪΐͬͱҧ͏ॲཧzΛ ϒϩοΫͱͯ͠ड͚औΔ
“ EPFOE·ͨ\^Ͱғ·Εͨίʔυͷஅย ϒ ϩοΫͱݺΕΔ ΛޙΖʹ͚ͯϝιουΛݺͼग़ ͢ͱɺͦͷϝιουͷ෦͔ΒϒϩοΫΛධՁͰ͖ ·͢ɻ ϒϩοΫ͖ϝιουΛࣗͰఆٛ͢ΔʹZJFME ࣜΛ͍·͢ɻ
‣ ॲཧΛΦϒδΣΫτͱͯ͠நԽͨ͠ͷɻ ‣ 3VCZͷಛਓؾϙΠϯτͷͭ ‣ ͍ΘΏΔʮߴ֊ؔʯ ‣ DBMMͰॲཧΛݺͼग़͢ɻ ϒϩοΫ
‣ ;ͭ͏ͷ܁Γฦ͠ ‣ .PEFMBMMFBDIEPFOE ‣ ॲཧͷڥք ‣ .PEFMUBOTBDUJPOEPFOE ‣ %4-
‣ 3BJMTBQQMJDBUJPOSPVUFTESBXEPFOE ‣ 34QFDͷMFU 3BJMTΞϓϦʹ͓͚ΔϒϩοΫ
‣ ϥΠϒϥϦ੍͕ޚߏΛࢦఆ͍ͯ͠Δ ‣ ݺͼग़͠ଆͷ۩ମతͳॲཧࣗମΛϒϩοΫͱͯ͠ड͚ɺ ϥΠϒϥϦϑϨʔϜϫʔΫͰ४උ্ͨ͠Ͱݺͼग़͢ɻ ‣ ͰɺऔΒΕͨؾ͕͠ͳ͍ ‣ FBDIUSBOTBDUJPOී௨ʹಡΊΔ ϒϩοΫΛΑ͘ݟͯΈΔͱ
model.transaction do model1.save! model2.save! end ྫ
module Transactionable def transaction do_begin do_something do_commit rescue
do_rollback class Model include Transactionable private def do_something model1.save! model2.save! NJYJOͰॻ͍ͯΈΔ
class MyModel < AbstractModel private def do_something model1.save!
model2.save! ςϯϓϨʔτϝιουͰॻ͍ͯΈΔ class AbstractModel def transaction do_begin do_something do_commit rescue do_rollback private def do_something raise NotImplementedError
class SaveStrategy def initialize(*models) def do_something @models.each(&:save!) ...
s = SaveStrategy.new( model1, model2 ) model.transaction(s) ετϥςδʔͰॻ͍ͯΈΔ class Model def transaction(strategy) do_begin strategy.do_something do_commit rescue do_rollback
class Model def transaction(&strategy) do_begin strategy.call # or
yield do_commit rescue do_rollback ϒϩοΫΛड͚͚Δ model.transaction do model1.save! model2.save!
‣ DBMMΛڞ௨ΠϯλʔϑΣʔεͱͨ͠ετϥςδʔͱ ݴ͑Δɻ ‣ ͍ΘΏΔDBMMBCMFPCKFDU ‣ ϒϩοΫΛ͏ͱɺΞϓϦέʔγϣϯίʔυͷಡΈ खͷίϯςΩετ͕ܧଓ͢Δɻ ‣ CJOEJOHQSZΛೖΕΔͱ͜Ζ͕ࣗ໌
ϒϩοΫͱετϥςδʔ
class MyModel < AbstractModel private def do_something model1.save!
model2.save! ྫEP@TPNFUIJOH͕ݺΕͯͳͦ͞͏ͳͱ͖Ͳ͏͢Δ class AbstractModel def transaction do_begin do_something do_commit rescue do_rollback private def do_something raise NotImplementedError
‣ ϒϩοΫΛड͚͚Δͱɺʮͪΐͬͱҧ͏ॲཧ Λࠩ͠ࠐ·͍ͤͨʯͱ͖ʹͷ੍ޚߏΛݺͼग़ ͠ଆʹҕͶ͍ͯΔΑ͏ʹݟͤΒΕΔɻ ‣ ͦ͏͍͏ؾ࣋ͪͰ͑Δͷ͕େࣄɻ ‣ 3VCZͬΆ͍ίʔυʹͳΔɻ
‣ ͳͥϑϨʔϜϫʔΫʹ͠ͳ͍΄͏͕Α͍͔ ‣ ϑϨʔϜϫʔΫΛ࡞Βͳ͍ํ๏ ‣ ςϯϓϨʔτϝιουΛආ͚ͯ;ͭ͏ʹϝιουʹநग़͢Δ ‣ ςϯϓϨʔτϝιουΑΓετϥςδʔͰ֦ுͤ͞Δ ‣ lͪΐͬͱҧ͏ॲཧzΛදݱ͢ΔͨΊʹϒϩοΫΛड͚͚Δ
‣ ·ͱΊ੍ޚߏΛ͍खʹҕͶΔ
·ͱΊ ੍ޚߏΛ ͍खʹҕͶΔ
‣ ศརϥΠϒϥϦ͕ศརͳͷؒҧ͍ͳ͍ɻ ‣ ੍ޚߏΛͯ͠͠ͳͯ͘ɺศརϝιουΛఏڙ͢Δͷ͕ेศར ‣ ʮͪΐͬͱҧ͏ॲཧʯετϥςδʔͰදݱ͢Δɻ ‣ ܧঝͤͯ͞ݺͼग़͢ॲཧ͚ͩΛॻ͔ͤͳ͍ ‣ ϒϩοΫ͍͍Ϡπɻੵۃతʹ׆༻͠·͠ΐ͏ɻ
‣ 3VCZ͍͍ΑͶ ϥΠϒϥϦίʔυͱΞϓϦίʔυΛૄʹอͭ
‣ ϔϧύʔϝιουΛɺετϥςδʔύλʔϯΛɺϒϩοΫΛ ͑Α͍Θ͚Ͱͳ͍ɻ ‣ 'PP'SBNFXPSLOBOUPLB@QSPD DPOUFYU \^Έ͍ͨͳ ‣ ͍ͭɺͲ͏ݺΕΔͷ
‣ ʮࠓ͜ͷศརϥΠϒϥϦΛॻ͍ͯΔࣗɺͦΕ͕ Ͳ͏ΘΕΔ͔·ͩΒͳ͍ʯͱ͍͏ؾ࣋ͪʹ͖߹͏ɻ )PXʹ͍ͭͯ͠·͕ͨ͠
‣ ·ͩݟ͵ΞϓϦέʔγϣϯίʔυʹɺඞཁҎ্ͷ ੍Λ՝͞ͳ͍Α͏ʹ͢Δɻ ‣ ΞϓϦέʔγϣϯͰԿΛ͍͔ͨ͠ɺͦͷͱ͖ʹͳΒͳ͍ͱΘ͔Βͳ͍ɻ ‣ ͦͷ࣌ɺͦͷਓୡ͕ɺ͖߹͑Δ༨Λ͢ɻ ‣ ۩ମతͳʹ͖߹͍ͬͯΔਓΛϦεϖΫτɻະདྷͷ͔ࣗ ੍ޚߏΛ͍खʹҕͶΔ