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
A Philosophy of Software Design 前半
Search
Yosuke Furukawa
PRO
February 28, 2022
Programming
26
11k
A Philosophy of Software Design 前半
2022/02/28 に MoneyForward で発表した A Philosophy of Software Design の話です。
Yosuke Furukawa
PRO
February 28, 2022
Tweet
Share
More Decks by Yosuke Furukawa
See All by Yosuke Furukawa
Welcome JSConf.jp 2024
yosuke_furukawa
PRO
1
3.7k
tc39 x jsconf.jp Panel Discussion 2024
yosuke_furukawa
PRO
0
190
Removing Corepack
yosuke_furukawa
PRO
9
1.5k
JavaScript Runtime とはなにか
yosuke_furukawa
PRO
15
2.6k
Strip Types と Storage
yosuke_furukawa
PRO
4
370
Module Harmony について
yosuke_furukawa
PRO
3
1.6k
LTのやり方
yosuke_furukawa
PRO
16
2.4k
AppRouter Panel Talk
yosuke_furukawa
PRO
3
750
Node.js v22 で変わること
yosuke_furukawa
PRO
13
5.8k
Other Decks in Programming
See All in Programming
PHPカンファレンス名古屋2025 タスク分解の試行錯誤〜レビュー負荷を下げるために〜
soichi
1
520
法律の脱レガシーに学ぶフロントエンド刷新
oguemon
5
740
さいきょうのレイヤードアーキテクチャについて考えてみた
yahiru
3
760
一休.com のログイン体験を支える技術 〜Web Components x Vue.js 活用事例と最適化について〜
atsumim
0
660
Honoをフロントエンドで使う 3つのやり方
yusukebe
7
3.4k
Multi Step Form, Decentralized Autonomous Organization
pumpkiinbell
1
800
.NET Frameworkでも汎用ホストが使いたい!
tomokusaba
0
170
CI改善もDatadogとともに
taumu
0
170
Lottieアニメーションをカスタマイズしてみた
tahia910
0
130
How mixi2 Uses TiDB for SNS Scalability and Performance
kanmo
40
15k
sappoRo.R #12 初心者セッション
kosugitti
0
260
color-scheme: light dark; を完全に理解する
uhyo
6
460
Featured
See All Featured
Faster Mobile Websites
deanohume
306
31k
Fireside Chat
paigeccino
34
3.2k
Why Our Code Smells
bkeepers
PRO
336
57k
Writing Fast Ruby
sferik
628
61k
Fantastic passwords and where to find them - at NoRuKo
philnash
51
3k
The Myth of the Modular Monolith - Day 2 Keynote - Rails World 2024
eileencodes
21
2.5k
Testing 201, or: Great Expectations
jmmastey
42
7.2k
Performance Is Good for Brains [We Love Speed 2024]
tammyeverts
7
630
Statistics for Hackers
jakevdp
797
220k
Agile that works and the tools we love
rasmusluckow
328
21k
Why You Should Never Use an ORM
jnunemaker
PRO
55
9.2k
How to train your dragon (web standard)
notwaldorf
91
5.8k
Transcript
A philosophy of software design (લ) 2022/2/28 @ MoneyForward ษڧձ
Twitter: @yosuke_furukawa Github: yosuke-furukawa
A philosophy of software design • 2018ʹॳ൛͕ϦϦʔε͞Ε • 2020ʹୈೋ൛͕ϦϦʔε͞Εͨ •
Ͱ͍͏ͱʮιϑτΣΞઃܭͷֶʯ https://www.amazon.co.jp/dp/B07N1XLQ7D/
A philosophy of software design • ஶऀδϣϯɾΦʔελʔϋτ͞Μ • Stanford େֶͷίϯϐϡʔλαΠΤϯεڭत
• Sprite OS (OS), Tcl.Tk(ϓϩάϥϛϯάݴޠ), RAMCloud (ΫϥυγεςϜ) ͳͲͳͲɺ੍ ࡞ଟ https://web.stanford.edu/~ouster/cgi-bin/ home.php
A philosophy of software design ͷݴ͍͍ͨࠜຊʹ͋Δͱ͜Ζ • ιϑτΣΞͷઃܭָ͍͠ • ७ਮͳ࡞աఔͷதͰύζϧͷΑ͏ʹͲ͏ͬͯઃܭ͢Δ͔
Λߟ͑Δ͜ͱɺͦΕΛ࣮͢Δ͜ͱͷָ͍͘͢͜͝͠ͱ • ͜ͷ෦Λָ͠ΊΔΑ͏ʹͳͬͯ΄͍͠ • ٯʹݴ͏ͱΞυϗοΫʹϫʔʔ͍͖ͬͯͳΓॻ͍ͪΌ͔ͬͯ ΒςετΛॻ͍ͨΓ৭ʑޙ͔Βྑ͘͢ΔɺΈ͍ͨͳ͜ͱࠓ ͷτϨϯυͰ͋Δͷͷɺྑ͍࡞աఔʹͳ͍ͬͯͳ͍
ͦͦઃܭϓϩηεΛͪΌ Μͱఔͱ͍ͯͬͯ͠Δͱ ͜Ζগͳ͍
ྫ͑... • ΞδϟΠϧ։ൃ • εϓϦϯτͰ2िؒͷΰʔϧΛܾΊͯͦΕʹ͚ͯ ։ൃΛ͍ͯ͘͠ • ͢ΔͱͲ͏࣮ͯ͠ʹλεΫ͕ϑΥʔΧε͞ΕΔ • ݁Ռͱͯ͠࠷ॳ͔Βʮϫʔʔ࣮ͬͯͯ͠ɺޙ͔Β
ςετॻ͘ʯʹͳΓ͕ͪ
ྫ͑... • ҰਓͷϑϧελοΫϓϩάϥϚʔ͚͕ͩΞαΠ ϯ͞ΕͯϓϩδΣΫτΛճ͠ଓ͚ΔΑ͏ͳঢ়گ • ԿͰΒͳ͍ͱ͍͚ͳ͍ঢ়گʹ͍ࠐ·Εͯ Δ • ϫʔʔͬͱॻ͚ͩ͘ʹͳΓ͕ͪɺͱ͍͏͔ͦ ͏͡Όͳ͍ͱऴΘΒͳ͍ঢ়گʹͳͬͯΔ
ྫ͑... • ͳΜͱͳ͘ͷ֤ʹؕΓ͕ͪ • ϑϨʔϜϫʔΫԿΛ͏ʁ • πʔϧΛͲ͏͢Δʁ • ςετͲ͏ͬͯॻ͘ʁ •
Ͳ͏ͬͯ࡞Δ͔ͷٞΑΓલʹ͜ͷ͕དྷͯ͠·͏έʔε͕༗Δɻ • ͜ͷखͷϑϨʔϜϫʔΫπʔϧͷબఆ࣮ʹ͍ۙ • ܾΊͨΒʮϫʔʔͬͱॻ͘ʯࣄʹΓ͕ͪ
͜͏͍͏ʮϫʔʔͬͱॻͩ͘ ͚ॻ͘ʯͱ͍͏ϓϩάϥϛϯ άΛ൱ఆ͍ͯ͠Δ
tactical programming vs strategic programming • ʮϫʔʔͬͱॻ͚ͩ͘ॻ͘ʯͱ͍͏ͷ͜ͷຊͰ tactical programming ͱݺΕ͓ͯΓɺ൱ఆ͞Ε͍ͯΔɻ
• ·ͣͲ͏ͬͯෳࡶ͞ΛΓ͚Δ͔ͱݴͬͨͷղ ͱͦΕΛͲ͏ͬͯදݱ͢Δ͔ͱ͍͏நԽΛͪΌΜͱߦ ͏͖ͩͱ͍͏ओு • ͜ͷෳࡶ͞ͱ͖߹ͬͯίʔυΛॻ͘͜ͱΛʮstrategic programmingʯ ͱݺΜͰ͓Γɺͪ͜ΒΛਪ͍ͯ͠Δɻ
ෳࡶ͞ͱ͖߹͏
ιϑτΣΞ։ൃʹෳࡶ͕͞ ͖ͭͷ • ෳࡶ͞ͷΓཱͪΛΓ • ෳࡶ͞ΛͲ͏ͬͯॲཧ͢Δ͔Λߟ͑Δ • ͦΕ͕ͦ͜ "ઃܭ" Ͱ͋Δ
ͦͦෳࡶ͞ͱ
ෳࡶ͞ • "Complexity is anything related to the structure of
a software system that makes it hard to understand and modify the system." • ʮෳࡶ͞ͱιϑτΣΞγεςϜͷߏʹ ؔͯ͠ɺγεςϜͦͷͷΛཧղɾมߋ͠ʹ͘ ͍ͯ͘͠ΔԿ͔ʯͰ͋Δɻ
ෳࡶ͞ʹΑͬͯҾ͖ى͜͞ΕΔ ঢ়ଶ • มߋͷ֦େԽ (Change Amplification) • ೝෛՙͷ૿Ճ (Cognitive Load)
• Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns)
มߋͷ֦େԽ (Change Amplification) • มߋՕॴ͕ଟ͘ͳΔ͜ͱ • ҰՕॴม͑ΕࡁΈͦ͏ͳมߋ͚ͩͲɺ࣮ผͳՕॴ ม͑ͳ͖Ό͍͚ͳ͍έʔε • ྫ͑ɺഎܠ৭ͷมΛݸʑͷϖʔδ͕͍࣋ͬͯͯɺશ
ମΛม͑Δ࣌ʹҰݸҰݸͷϖʔδʹมߋ͕ٴΜͰ͠·͏ • ͜͏͍͏ͷมߋՕॴͷӨڹΛ࠷খݶʹ͠Α͏ͱͨͨ͠ Ίʹ tactic ͳίʔυ͕ੵΈॏͳͬͯى͖Δ
มߋͷ֦େԽ (Change Amplification) ҰՕॴͰม͑ΒΕΔΑ͏ʹͳ͍ͬͯͳ͍ྫ
ೝෛՙͷ૿Ճ (Cognitive Load) • ୯७ʹಡΈʹ͍͘ίʔυ • ίʔυ͕ϕλοͱॻ͔Ε͍ͯͯɺؔͱ͔Ϋϥε ͱ͔ͰͪΌΜͱׂ͞Εͯͳ͔ͬͨΓɺҰՕॴͰ ৭ʑΓ͗ͩͬͨ͢Γɺͦͦมɾ໊͕ؔ ײͱ߹Θͳ͔ͬͨΓ
• Α͘ݴΘΕͯΔΫιίʔυͬͯݺΕͨΓɺώϤ ίʔυͬͯݺΕͨΓ͢Δͭ
Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns) • ༁͢ΔͱʮΒͳ͍͜ͱʯΛΒͳ͍͜ͱ • ͦͷλεΫΛऴ͑ΔͷʹͲ͜·ͰνΣοΫ͢Ε͍ ͍͔͕ෆ໌ྎͳ͜ͱ • มߋͨ͠Βʮ࣮͜͜ʹӨڹ͋Γ·ͨ͠ʔʯͳࣄ
͕ӅΕͯΔ • ʮӅΕͨӨڹ㲈Α͘Βͳ͍͜ͱʯ͕Θ͔Βͳ͍͜ͱ
Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns) ҰՕॴͰม͑ΒΕΔΑ͏ʹͳͬͨͷͷɺ࣮ emphͱ͍͏ผͳछྨͷมͰݸʑʹϖʔδ৭੍͕ޚ͞Ε͍ͯΔྫ FNQI͕ VOLOPXO
ͳΜͰෳࡶʹͳΔͷ͔
ෳࡶʹͳΔཧ༝ • "Complexity comes from an accumulation of dependencies and
obscurities. (snip) As a result, it takes more code modifications to implement each new feature." • ʮෳࡶ͞ґଘͱᐆດ͞ͷੵ͔ΒͨΒ͞ ΕΔɻ݁Ռͱͯ͠কདྷͷػೳ࣮ͷͨΊʹΑ Γଟ͘ͷίʔυมߋ͕ඞཁʹͳΔʯ
ґଘ (dependencies) • ґଘࣗମආ͚ΒΕͳ͍ • ϥΠϒϥϦͷґଘ • ࣗͷ࡞ͬͨผͳΫϥεͷґଘ • ඞͣଘࡏ͢ΔɺΉ͠Ζແ͠Ͱ։ൃ͕Ͱ͖
ͳ͍
ґଘ (dependencies) • ॏཁͳͷґଘͦͷͷΛආ͚Δ͜ͱͰͳ ͘ɺԿͷͨΊʹґଘ͍ͯ͠Δͷ͔ɺͲ͏ͬͯ ґଘ͍ͯ͠Δͷ͔Λ໌֬ʹ͢Δ͜ͱ • background color ͷྫͰݴ͑ɺ͜ΕΛม͑
Εશͯͷഎܠ৭͕มΘΔ͜ͱΛ໌֬ʹ͢Δɻ • ٯʹݴ͑ෆ໌ྎͳґଘආ͚Δɻ
ᐆດ͞ (obscurity) • ᐆດͳίʔυͷྫ • Ұൠత͗͢Δม໊ (data, time, num) •
υΩϡϝϯτʹ୯Ґ͕໌ه͞Ε͍ͯͳ͍ (width, height => pixel? inch? cm?) • Ұ؏ੑ͕ͳ͍ίʔυ • ґଘʹΑͬͯᐆດ͕͞Ҿ͖ى͜͞ΕΔέʔε༗Δ • ґଘͨ͠ίʔυͷதͰ৽͍͠Τϥʔ͕Ճ͞ΕͨΓɺڍಈͷมߋ͕ ى͖ͯͦΕ͕໌ه͞Ε͍ͯͳ͔ͬͨΓ
ᐆດ͞ (obscurity) • Ұ൪ଟ͍ͷʮυΩϡϝϯτෆʯʹΑΔᐆ ດ͞ • ͳΜͰυΩϡϝϯτʹॻ͚Αͱ͍͏Ͱ ͳ͍ɻ • γϯϓϧͳઃܭʹΑͬͯυΩϡϝϯτ͕ͦ͜
·Ͱඞཁͳ͘ͳΔ͜ͱ͋Δ
Strategic Programming
Strategic Programming • ϫʔʔͬͱίʔυΛॻ͘ tactical programming Ͱͳ͘ɺ ෳࡶ͞ͱ͖߹͏ Strategic Programming
Λਪ͍ͯ͠Δ • Α͋͘Δٕज़తෛ࠴ tactical programming ʹΑͬͯى͜Δ • Strategic Programming ʹࢿϚΠϯυ͕ඞཁ • ࠷Λࢦͯ͠ίʔυΛॻ͍ͯऴΘΒͤΑ͏ͱ͢ΔͷͰͳ ͘ɺҰ୴ෳࡶ͞ͱ͖߹ͬͯઃܭͷྑ͠ѱ͠Λߟ͑ͳ͕Β ίʔυΛॻ͘͜ͱ͕ॏཁ
ࢿϚΠϯυ • ྑ͍ઃܭແྉͰ࡞Εͳ͍ • ແྉͰͳ͍ͷͰߟ͑Δ͕࣌ؒඞཁʹͳΔ͕ɺશମͷίετͷ ɺ10-20%ఔઃܭʹͬͯྑ͍ͱචऀݴ͍ͬͯΔɻ • ࠷ॳͯ͘ঃʑʹ্͕͍ͬͯ͘ •
Strategic Programming • Deep Module Λ࡞Δ • దʹϑΝΠϧΛ͚ͯɺదʹϑΝΠϧΛ ౷߹͢Δ •
ϨΠϠ͝ͱʹநԽͷํΛม͑Δ • ྫ֎Λఆٛ͢Δ
Deep Module Λ࡞Δ • நԽͷ伴ใΛ࠷খݶʹߜΔ͜ͱ • Shallow Module Έ͍ͨͳ୯ʹ࣮͕؆୯Ͱதͷബ͍Ϟδϡʔ ϧ͔ΓʹͳΔ͜ͱආ͚ͳ͚Ε͍͚ͳ͍
• ΠϯλϑΣʔεγϯϓϧʹɺ࣮खް͘ •
Deep Module Λ࡞Δ • ྫ͑ • Java I/O ΫϥεͷσβΠϯ shallow
module ʹͳ͍ͬͯΔ ͜Ε͕ࣗѱ͍ɺͱ͍͏༁Ͱͳ͍͕ όοϑΝ͢Δ͔͠ͳ͍͔͕બΔσβΠϯ
Deep Module Λ࡞Δ • ྫ͑ • ΠϯλϑΣʔεҰ൪Α͋͘ΔέʔεΛ୯७ ʹ͑ΔΑ͏ʹઃܭ͞Ε͍ͯΔ͖ • ຆͲͷϢʔβʔ͕bufferͯ͠͏͜ͱ͕جຊ
ʹͳΔͷͰ͋ΕɺͦΕ͕؆୯ʹͰ͖Δσ βΠϯͰ͋Δ͖
దʹϑΝΠϧΛ͚Δ దʹϑΝΠϧΛ౷߹͢Δ • Ͳ͜Ͱׂͯ͠Ͳ͜Ͱ౷߹͢Δ͔͕Ұ൪جຊతͳઃܭ • ౷߹͢Δͱ͖: • ใ͕ڞ༗͞ΕͯΔ࣌ (ྫ component
1 ͱ 2 ಉ͡ σʔλΛ͏) • ΠϯλϑΣʔεΛγϯϓϧʹͰ͖Δ࣌ • ॏෳΛഉআͰ͖Δ࣌
దʹϑΝΠϧΛ͚Δ దʹϑΝΠϧΛ౷߹͢Δ • ׂ͢Δ࣌ • త͕ҟͳΔ࣌: ҰൠతͳͷͱಛԽͨ͠ͷͰ͚Δɻ • ͦͷΘΓɺݺͼ͚ΔΑ͏ͳͷۃྗආ͚Δ •
ϨΠϠ͝ͱʹநԽΛม͑Δ • ϑΝΠϧγεςϜ • ϨΠϠʹHDDͷϒϩοΫ͕͋ͬͨΓɺσόΠευϥΠό͕ͦ ΕΛѻ͍ͬͯͨΓ͢Δ͕ɺߴϨΠϠͰͦΕΒΛҙࣝ͠ͳ͍Ͱѻ ͑ΔΑ͏ʹͳ͍ͬͯͨΓ͢Δɻ • ·ΕʹσʔλΛΩϟογϡ͢Δ͋ͬͨΓ͢Δɻ •
ωοτϫʔΫɾϓϩτίϧ • TCP Ͱ৴པੑͷߴ͍ϓϩτίϧΛ࡞Γͭͭͦͷ্ͰϨΠϠΛҙ ࣝ͠ͳ͍Α͏ʹͰ͖͍ͯΔ
ϨΠϠ͝ͱʹநԽΛม͑Δ • pass through ආ͚Δ • pass through ݺͼग़ͨ͠ϝιου͕ผͳϝ ιουΛͨͩݺͿ͚ͩͷߦҝ
• pass through ϝιουΛ shallow ʹͯ͠ ͠·͏
ྫ֎Λఆٛ͢Δ • ྫ֎Λग़͖͔͢ʁ͔Βߟ͑Δ • ྫ֎ΛҿΈࠐΉΈ • ͪΌΜͱྫ֎ΛͱυΩϡϝϯτʹ͢
ྫ֎Λग़͖͔͢ʁ͔Βߟ͑Δ • ྫ: Tcl ͰͷؒҧͬͨσβΠϯ • unset ͱ͍͏มͷதΛআ͢ΔΈΛݴޠʹೖΕͨʢGC͕ͳ͍͔Β ͬͨมΛআͯ͠΄͍࣌͠ͷΈʣ •
ͨͩ͠ɺະఆٛͷมΛ unset ͨ͠߹ϓϩάϥϛϯάͷόάͱͯ͠ྫ֎ Λεϩʔ͢Δઃܭʹͯ͠͠·ͬͨɻ • ݁Ռͱͯ͠ɺͲͷมΛఆ͔ٛͨ͠ΛϓϩάϥϚʔ͕͍֮͑ͯͳ͍ͱ͍͚ͳ ͘ͳͬͯ͠·ͬͨɻ • catch Ͱશ෦ͬͯ͘͘ɺҰ୴ແࢹΈ͍ͨͳΞϯνύλʔϯ͕ੜ·Εͯ͠·ͬͨ
ྫ֎Λग़͖͔͢ʁ͔Βߟ͑Δ • ྫ֎Λग़͞ͳ͍ઃܭ͋Δ • substring ϝιουʹ͍ͭͯߟ͑Δ • substring(start, end) Ͱ
end < start ͩͬͨ࣌ʹྫ ֎Λεϩʔ͢Δ͔൱͔ʁ • Java ྫ֎Λεϩʔ͢Δ͕ɺ Python ۭͷจࣈ ྻΛฦ͢
ྫ֎Λग़͖͔͢ʁ͔Βߟ͑Δ • Windows ͷϑΝΠϧγεςϜআରͷϑΝΠ ϧ͕ಡࠐதͩͬͨ࣌ʹಡΈࠐΈ͕ऴΘΔ·Ͱͭ ͱ͍͏σβΠϯɺ݁Ռͱͯ͠γεςϜશମ͕ halt ͯ͠͠·͏ • Unix
ͷϑΝΠϧγεςϜͦ͏Ͱͳ͘ɺϑΝΠ ϧΛҰ୴ಡΊΔॴʹ֬อ͔ͯ͠ΒಡΈࠐΈͱॻ ͖ग़͠ผ్ߦ͏
ྫ֎ΛҿΈࠐΉ • TCPଟগͭͳ͕Βͳ͔ͬͨΓɺྫ֎తͳঢ় گʹͳͬͨͱͯࣗ͠ͷதͰղܾ͢Δ • ϦτϥΠͨ͠ΓɺޡΓగਖ਼ͨ͠Γ͢Δ • ຊʹແཧͳঢ়گʹͳͬͨͱ͖͚ͩྫ֎Λ ্͛Δ
ྫ֎ΛҿΈࠐΉ • ͜͏͍͏ͱ͖ຊʹྫ֎తͳঢ়گͰ͋Γɺ ͦͷͱ͖Ұ୴Ϋϥογϡͤͯ͞ϦΧόϦ͢ ΔͳΓɺͳΜͳΓͷରॲΛ্ҐϨΠϠʹٻΊ Δ
ͪΌΜͱྫ֎ΛυΩϡϝϯτʹ ͢ • ͲΜͳঢ়گͷྫ֎ͳͷ͔Λ໌ه͢Δ • Կ͕ॏཁͰԿ͕ॏཁͰͳ͍͔Λॻ͔ͳ͍ͱ͍͚ ͳ͍ • ॏཁ͡Όͳ͍ྫ֎Ӆͤͳ͍͔Λݕ౼͢Δ͖ •
ॏཁͳྫ֎υΩϡϝϯτʹ໌ه͠ͳ͚Εͳ Βͳ͍
design it twice
ೋճઃܭ͠Ζ design it twice • ΤσΟλͷઃܭҰͭͱͬͯෳͷநԽͷઃܭ͕͋ΓಘΔ • ߦࢤͷΠϯλϑΣʔε • ྻࢤͷΠϯλϑΣʔε
• จࣈྻࢤͷΠϯλϑΣʔε • ҰճͷઃܭͰͯ͢ͷϝϦοτͱσϝϦοτΘ͔Βͳ͍ • ઃܭೋճͯ͠ΈΔʢ࣌ؒͷڐ͢ݶΓʣ
·ͱΊ • Tactical Programming ΊΑ͏ • Strategic Programming Λਪ •
ෳࡶ͞ґଘͱᐆດ͔͞Βى͖Δ • ෳࡶ͞มߋ૿େɺೝෛՙɺΑ͘Βͳ͍͜ͱΛ૿Ճͤ͞Δ • Strategic Programming ͜ΕΒΛߟ͑ͨ͢ΊͷҰॿͱͳΔͷ • ࢿϚΠϯυͰߟ͑ͯϓϩάϥϛϯά͢Δ