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
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
軽量Java基盤の設計 DIコンテナに頼らない、長期保守と1秒起動の実現 JJUG CCC 2026 Spring
macha64
0
540
AIで効率化できた業務・日常
ochtum
0
140
AI時代のUIはどこへ行く?その2!
yusukebe
22
7.4k
Performance Engineering for Everyone
elenatanasoiu
0
180
技術的負債解消で開発者の未来を開く- AIの力でコード刷新
kmd2kmd
0
110
IBM Bobを活用したレガシーアプリの最新化
oniak3ibm
PRO
1
200
TAKTでAI駆動開発の品質を設計する
j5ik2o
7
1.4k
「エンジニアインターン、どうやって取った?」準備のリアルを語るLT会 Progate BAR
akiomatic
0
140
その問い、本当に正しいですか?AI時代のエンジニアに必要な哲学と認知科学 / ai-philosophy-cognitive-science
minodriven
11
5.8k
並列実装の現場、2ヶ月間実務でAIを使い倒したAIもPCも私も限界が近い
ming_ayami
0
130
jQueryをバージョンアップする前に使いたいjQuery Migrate
matsuo_atsushi
0
560
AIだと陥りがちなJakarta EE最新技術への移行時の落とし穴と解決策
tnagao7
0
110
Featured
See All Featured
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
230
Site-Speed That Sticks
csswizardry
13
1.2k
How to Think Like a Performance Engineer
csswizardry
28
2.7k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
287
14k
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.3k
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
71
40k
Money Talks: Using Revenue to Get Sh*t Done
nikkihalliwell
0
250
Building Adaptive Systems
keathley
44
3.1k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
10
1.2k
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
370
Practical Orchestrator
shlominoach
191
11k
Writing Fast Ruby
sferik
630
63k
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ʹ͍ͭͯ͠·͕ͨ͠
‣ ·ͩݟ͵ΞϓϦέʔγϣϯίʔυʹɺඞཁҎ্ͷ ੍Λ՝͞ͳ͍Α͏ʹ͢Δɻ ‣ ΞϓϦέʔγϣϯͰԿΛ͍͔ͨ͠ɺͦͷͱ͖ʹͳΒͳ͍ͱΘ͔Βͳ͍ɻ ‣ ͦͷ࣌ɺͦͷਓୡ͕ɺ͖߹͑Δ༨Λ͢ɻ ‣ ۩ମతͳʹ͖߹͍ͬͯΔਓΛϦεϖΫτɻະདྷͷ͔ࣗ ੍ޚߏΛ͍खʹҕͶΔ