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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
490
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
650
Other Decks in Programming
See All in Programming
脅威をエンジニアリングの糧にして――現場編 / Turning Threats into Engineering Fuel — Field Edition
nrslib
0
290
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
560
AI 輔助遺留系統現代化的經驗分享
jame2408
1
760
スマートグラスで並列バイブコーディング
hyshu
0
160
Developing with AI Agents — Codex, Claude Code & Cowork Practical Guide
x5gtrn
PRO
0
1.3k
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
OSもどきOS
arkw
0
570
Mujeres en SEO Summit 2026 - Greatest Disaster Hits en Web Performance
guaca
0
190
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
依存関係から依存物へ―Dependencyという言葉の歴史をひも解く
j_lee
0
120
Datadog × OpenTelemetry 入門と実践のあいだ
kn_to_maxpno
1
160
メソッドのジェネリクスでGoの夢は広がるか? / Kyoto.go #65
utgwkk
3
840
Featured
See All Featured
How To Stay Up To Date on Web Technology
chriscoyier
790
250k
Code Review Best Practice
trishagee
74
20k
The AI Search Optimization Roadmap by Aleyda Solis
aleyda
1
5.9k
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
11
950
AI: The stuff that nobody shows you
jnunemaker
PRO
8
720
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
GraphQLとの向き合い方2022年版
quramy
50
15k
Building Adaptive Systems
keathley
44
3.1k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
290
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
62
44k
Visualization
eitanlees
152
17k
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ʹ͍ͭͯ͠·͕ͨ͠
‣ ·ͩݟ͵ΞϓϦέʔγϣϯίʔυʹɺඞཁҎ্ͷ ੍Λ՝͞ͳ͍Α͏ʹ͢Δɻ ‣ ΞϓϦέʔγϣϯͰԿΛ͍͔ͨ͠ɺͦͷͱ͖ʹͳΒͳ͍ͱΘ͔Βͳ͍ɻ ‣ ͦͷ࣌ɺͦͷਓୡ͕ɺ͖߹͑Δ༨Λ͢ɻ ‣ ۩ମతͳʹ͖߹͍ͬͯΔਓΛϦεϖΫτɻະདྷͷ͔ࣗ ੍ޚߏΛ͍खʹҕͶΔ