$30 off During Our Annual Pro Sale. View Details »

A Philosophy of Software Design 前半

A Philosophy of Software Design 前半

2022/02/28 に MoneyForward で発表した A Philosophy of Software Design の話です。

Yosuke Furukawa
PRO

February 28, 2022
Tweet

More Decks by Yosuke Furukawa

Other Decks in Programming

Transcript

  1. A philosophy of software design (લ൒) 2022/2/28 @ MoneyForward ษڧձ

  2. Twitter: @yosuke_furukawa Github: yosuke-furukawa

  3. A philosophy of software design • 2018೥ʹॳ൛͕ϦϦʔε͞Ε • 2020೥ʹୈೋ൛͕ϦϦʔε͞Εͨ •

    ๜୊Ͱ͍͏ͱʮιϑτ΢ΣΞઃܭͷ఩ֶʯ https://www.amazon.co.jp/dp/B07N1XLQ7D/
  4. A philosophy of software design • ஶऀ͸δϣϯɾΦʔελʔϋ΢τ͞Μ • Stanford େֶͷίϯϐϡʔλαΠΤϯεڭत

    • Sprite OS (OS), Tcl.Tk(ϓϩάϥϛϯάݴޠ), RAMCloud (Ϋϥ΢υγεςϜ) ͳͲͳͲɺ੍ ࡞෺ଟ਺ https://web.stanford.edu/~ouster/cgi-bin/ home.php
  5. A philosophy of software design ͷݴ͍͍ͨࠜຊʹ͋Δͱ͜Ζ • ιϑτ΢ΣΞͷઃܭ͸ָ͍͠ • ७ਮͳ૑࡞աఔͷதͰύζϧͷΑ͏ʹͲ͏΍ͬͯઃܭ͢Δ͔

    Λߟ͑Δ͜ͱɺͦΕΛ࣮૷͢Δ͜ͱ͸΋ͷָ͍͘͢͜͝͠ͱ • ͜ͷ෦෼Λָ͠ΊΔΑ͏ʹͳͬͯ΄͍͠ • ٯʹݴ͏ͱΞυϗοΫʹϫʔʔ͍͖ͬͯͳΓॻ͍ͪΌ͔ͬͯ ΒςετΛॻ͍ͨΓ৭ʑޙ͔Βྑ͘͢ΔɺΈ͍ͨͳ͜ͱ͸ࠓ ͷτϨϯυͰ͸͋Δ΋ͷͷɺྑ͍૑࡞աఔʹ͸ͳ͍ͬͯͳ͍
  6. ͦ΋ͦ΋ઃܭϓϩηεΛͪΌ Μͱ޻ఔͱͯ͠΍͍ͬͯΔͱ ͜Ζ͸গͳ͍

  7. ྫ͑͹... • ΞδϟΠϧ։ൃ • εϓϦϯτͰ2िؒͷΰʔϧΛܾΊͯͦΕʹ޲͚ͯ ։ൃΛ͍ͯ͘͠ • ͢ΔͱͲ͏ͯ͠΋࣮૷ʹλεΫ͕ϑΥʔΧε͞ΕΔ • ݁Ռͱͯ͠࠷ॳ͔Βʮϫʔʔ࣮ͬͯ૷ͯ͠ɺޙ͔Β

    ςετॻ͘ʯʹͳΓ͕ͪ
  8. ྫ͑͹... • ҰਓͷϑϧελοΫϓϩάϥϚʔ͚͕ͩΞαΠ ϯ͞ΕͯϓϩδΣΫτΛճ͠ଓ͚ΔΑ͏ͳঢ়گ • ԿͰ΋΍Βͳ͍ͱ͍͚ͳ͍ঢ়گʹ௥͍ࠐ·Εͯ Δ • ϫʔʔͬͱॻ͚ͩ͘ʹͳΓ͕ͪɺͱ͍͏͔ͦ ͏͡Όͳ͍ͱऴΘΒͳ͍ঢ়گʹͳͬͯΔ

  9. ྫ͑͹... • ͳΜͱͳ͘ͷ֤࿦ʹؕΓ͕ͪ • ϑϨʔϜϫʔΫԿΛ࢖͏ʁ • πʔϧΛͲ͏͢Δʁ • ςετͲ͏΍ͬͯॻ͘ʁ •

    Ͳ͏΍ͬͯ࡞Δ͔ͷٞ࿦ΑΓ΋લʹ͜ͷ࿩͕དྷͯ͠·͏έʔε͕༗Δɻ • ͜ͷखͷϑϨʔϜϫʔΫ΍πʔϧͷબఆ͸࣮૷ʹ͍ۙ • ܾΊͨΒʮϫʔʔͬͱॻ͘ʯࣄʹ૸Γ͕ͪ
  10. ͜͏͍͏ʮϫʔʔͬͱॻͩ͘ ͚ॻ͘ʯͱ͍͏ϓϩάϥϛϯ άΛ൱ఆ͍ͯ͠Δ

  11. tactical programming vs strategic programming • ʮϫʔʔͬͱॻ͚ͩ͘ॻ͘ʯͱ͍͏ͷ͸͜ͷຊͰ͸ tactical programming ͱݺ͹Ε͓ͯΓɺ൱ఆ͞Ε͍ͯΔɻ

    • ·ͣͲ͏΍ͬͯෳࡶ͞Λ੾Γ෼͚Δ͔ͱݴͬͨ໰୊ͷ෼ղ ͱͦΕΛͲ͏΍ͬͯදݱ͢Δ͔ͱ͍͏ந৅ԽΛͪΌΜͱߦ ͏΂͖ͩͱ͍͏ओு • ͜ͷෳࡶ͞ͱ޲͖߹ͬͯίʔυΛॻ͘͜ͱΛʮstrategic programmingʯ ͱݺΜͰ͓Γɺͪ͜ΒΛਪ঑͍ͯ͠Δɻ
  12. ෳࡶ͞ͱ޲͖߹͏

  13. ιϑτ΢ΣΞ։ൃʹ͸ෳࡶ͕͞ ͖ͭ΋ͷ • ෳࡶ͞ͷ੒ΓཱͪΛ஌Γ • ෳࡶ͞ΛͲ͏΍ͬͯॲཧ͢Δ͔Λߟ͑Δ • ͦΕ͕ͦ͜ "ઃܭ" Ͱ͋Δ

  14. ͦ΋ͦ΋ෳࡶ͞ͱ͸

  15. ෳࡶ͞ • "Complexity is anything related to the structure of

    a software system that makes it hard to understand and modify the system." • ʮෳࡶ͞ͱ͸ιϑτ΢ΣΞγεςϜͷߏ଄ʹ ؔͯ͠ɺγεςϜͦͷ΋ͷΛཧղɾมߋ͠ʹ͘ ͍ͯ͘͠ΔԿ͔ʯͰ͋Δɻ
  16. ෳࡶ͞ʹΑͬͯҾ͖ى͜͞ΕΔ ঢ়ଶ • มߋͷ֦େԽ (Change Amplification) • ೝ஌ෛՙͷ૿Ճ (Cognitive Load)

    • ஌Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns)
  17. มߋͷ֦େԽ (Change Amplification) • มߋՕॴ͕ଟ͘ͳΔ͜ͱ • ҰՕॴม͑Ε͹ࡁΈͦ͏ͳมߋ͚ͩͲɺ࣮͸ผͳՕॴ΋ ม͑ͳ͖Ό͍͚ͳ͍έʔε • ྫ͑͹ɺഎܠ৭ͷม਺Λݸʑͷϖʔδ͕͍࣋ͬͯͯɺશ

    ମΛม͑Δ࣌ʹҰݸҰݸͷϖʔδʹมߋ͕ٴΜͰ͠·͏ • ͜͏͍͏ͷ͸มߋՕॴͷӨڹΛ࠷খݶʹ͠Α͏ͱͨͨ͠ Ίʹ tactic ͳίʔυ͕ੵΈॏͳͬͯى͖Δ
  18. มߋͷ֦େԽ (Change Amplification) ҰՕॴͰม͑ΒΕΔΑ͏ʹͳ͍ͬͯͳ͍ྫ

  19. ೝ஌ෛՙͷ૿Ճ (Cognitive Load) • ୯७ʹಡΈʹ͍͘ίʔυ • ίʔυ͕ϕλοͱॻ͔Ε͍ͯͯɺؔ਺ͱ͔Ϋϥε ͱ͔ͰͪΌΜͱ෼ׂ͞Εͯͳ͔ͬͨΓɺҰՕॴͰ ৭ʑ΍Γ͗ͩͬͨ͢Γɺͦ΋ͦ΋ม਺ɾؔ਺໊͕ ௚ײͱ߹Θͳ͔ͬͨΓ

    • Α͘ݴΘΕͯΔΫιίʔυͬͯݺ͹ΕͨΓɺώϤ ίʔυͬͯݺ͹ΕͨΓ͢Δ΍ͭ
  20. ஌Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns) • ௚༁͢Δͱʮ஌Βͳ͍͜ͱʯΛ஌Βͳ͍͜ͱ • ͦͷλεΫΛऴ͑ΔͷʹͲ͜·ͰνΣοΫ͢Ε͹͍ ͍͔͕ෆ໌ྎͳ͜ͱ • มߋͨ͠Βʮ࣮͸͜͜ʹ΋Өڹ͋Γ·ͨ͠ʔʯͳࣄ

    ͕ӅΕͯΔ • ʮӅΕͨӨڹ㲈Α͘஌Βͳ͍͜ͱʯ͕Θ͔Βͳ͍͜ͱ
  21. ஌Βͳ͍͜ͱͷ૿Ճ (Unknown Unknowns) ҰՕॴͰม͑ΒΕΔΑ͏ʹͳͬͨ΋ͷͷɺ࣮͸ emphͱ͍͏ผͳछྨͷม਺Ͱݸʑʹϖʔδ৭੍͕ޚ͞Ε͍ͯΔྫ FNQI͕ VOLOPXO

  22. ͳΜͰෳࡶʹͳΔͷ͔

  23. ෳࡶʹͳΔཧ༝ • "Complexity comes from an accumulation of dependencies and

    obscurities. (snip) As a result, it takes more code modifications to implement each new feature." • ʮෳࡶ͞͸ґଘͱᐆດ͞ͷ஝ੵ͔Β΋ͨΒ͞ ΕΔɻ݁Ռͱͯ͠কདྷͷػೳ࣮૷ͷͨΊʹΑ Γଟ͘ͷίʔυมߋ͕ඞཁʹͳΔʯ
  24. ґଘ (dependencies) • ґଘࣗମ͸ආ͚ΒΕͳ͍ • ϥΠϒϥϦ΁ͷґଘ • ࣗ෼ͷ࡞ͬͨผͳΫϥε΁ͷґଘ • ඞͣଘࡏ͢ΔɺΉ͠Ζແ͠Ͱ͸։ൃ͕Ͱ͖

    ͳ͍
  25. ґଘ (dependencies) • ॏཁͳͷ͸ґଘͦͷ΋ͷΛආ͚Δ͜ͱͰ͸ͳ ͘ɺԿͷͨΊʹґଘ͍ͯ͠Δͷ͔ɺͲ͏΍ͬͯ ґଘ͍ͯ͠Δͷ͔Λ໌֬ʹ͢Δ͜ͱ • background color ͷྫͰݴ͑͹ɺ͜ΕΛม͑

    Ε͹શͯͷഎܠ৭͕มΘΔ͜ͱΛ໌֬ʹ͢Δɻ • ٯʹݴ͑͹ෆ໌ྎͳґଘ͸ආ͚Δɻ
  26. ᐆດ͞ (obscurity) • ᐆດͳίʔυͷྫ • Ұൠత͗͢Δม਺໊ (data, time, num) •

    υΩϡϝϯτʹ୯Ґ͕໌ه͞Ε͍ͯͳ͍ (width, height => pixel? inch? cm?) • Ұ؏ੑ͕ͳ͍ίʔυ • ґଘʹΑͬͯᐆດ͕͞Ҿ͖ى͜͞ΕΔέʔε΋༗Δ • ґଘͨ͠ίʔυͷதͰ৽͍͠Τϥʔ͕௥Ճ͞ΕͨΓɺڍಈͷมߋ͕ ى͖ͯ΋ͦΕ͕໌ه͞Ε͍ͯͳ͔ͬͨΓ
  27. ᐆດ͞ (obscurity) • Ұ൪ଟ͍ͷ͸ʮυΩϡϝϯτෆ଍ʯʹΑΔᐆ ດ͞ • ͳΜͰ΋υΩϡϝϯτʹॻ͚Αͱ͍͏࿩Ͱ͸ ͳ͍ɻ • γϯϓϧͳઃܭʹΑͬͯυΩϡϝϯτ͕ͦ͜

    ·Ͱඞཁͳ͘ͳΔ͜ͱ΋͋Δ
  28. Strategic Programming

  29. Strategic Programming • ϫʔʔͬͱίʔυΛॻ͘ tactical programming Ͱ͸ͳ͘ɺ ෳࡶ͞ͱ޲͖߹͏ Strategic Programming

    Λਪ঑͍ͯ͠Δ • Α͋͘Δٕज़తෛ࠴͸ tactical programming ʹΑͬͯى͜Δ • Strategic Programming ʹ͸౤ࢿϚΠϯυ͕ඞཁ • ࠷଎Λ໨ࢦͯ͠ίʔυΛॻ͍ͯऴΘΒͤΑ͏ͱ͢ΔͷͰ͸ͳ ͘ɺҰ୴ෳࡶ͞ͱ޲͖߹ͬͯઃܭͷྑ͠ѱ͠Λߟ͑ͳ͕Β ίʔυΛॻ͘͜ͱ͕ॏཁ
  30. ౤ࢿϚΠϯυ • ྑ͍ઃܭ͸ແྉͰ࡞Εͳ͍ • ແྉͰ͸ͳ͍ͷͰߟ͑Δ͕࣌ؒඞཁʹͳΔ͕ɺશମͷίετͷ ಺ɺ10-20%ఔ౓͸ઃܭʹ࢖ͬͯྑ͍ͱචऀ͸ݴ͍ͬͯΔɻ • ࠷ॳ͸஗ͯ͘΋ঃʑʹ্͕͍ͬͯ͘ •

  31. Strategic Programming • Deep Module Λ࡞Δ • ద੾ʹϑΝΠϧΛ෼͚ͯɺద੾ʹϑΝΠϧΛ ౷߹͢Δ •

    ϨΠϠ͝ͱʹந৅Խͷํ਑Λม͑Δ • ྫ֎Λఆٛ͢Δ
  32. Deep Module Λ࡞Δ • ந৅Խͷ伴͸৘ใΛ࠷খݶʹߜΔ͜ͱ • Shallow Module Έ͍ͨͳ୯ʹ࣮૷͕؆୯Ͱத਎ͷബ͍Ϟδϡʔ ϧ͹͔ΓʹͳΔ͜ͱ͸ආ͚ͳ͚Ε͹͍͚ͳ͍

    • ΠϯλϑΣʔε͸γϯϓϧʹɺ࣮૷͸खް͘ •
  33. Deep Module Λ࡞Δ • ྫ͑͹ • Java I/O ΫϥεͷσβΠϯ͸ shallow

    module ʹͳ͍ͬͯΔ ͜Εࣗ਎͕ѱ͍ɺͱ͍͏༁Ͱ͸ͳ͍͕ όοϑΝ͢Δ͔͠ͳ͍͔͕બ΂ΔσβΠϯ
  34. Deep Module Λ࡞Δ • ྫ͑͹ • ΠϯλϑΣʔε͸Ұ൪Α͋͘ΔέʔεΛ୯७ ʹ࢖͑ΔΑ͏ʹઃܭ͞Ε͍ͯΔ΂͖ • ຆͲͷϢʔβʔ͕bufferͯ͠࢖͏͜ͱ͕جຊ

    ʹͳΔͷͰ͋Ε͹ɺͦΕ͕؆୯ʹͰ͖Δσ βΠϯͰ͋Δ΂͖
  35. ద੾ʹϑΝΠϧΛ෼͚Δ ద੾ʹϑΝΠϧΛ౷߹͢Δ • Ͳ͜Ͱ෼ׂͯ͠Ͳ͜Ͱ౷߹͢Δ͔͕Ұ൪جຊతͳઃܭ • ౷߹͢Δͱ͖: • ৘ใ͕ڞ༗͞ΕͯΔ࣌ (ྫ component

    1 ͱ 2 ͸ಉ͡ σʔλΛ࢖͏) • ΠϯλϑΣʔεΛγϯϓϧʹͰ͖Δ࣌ • ॏෳΛഉআͰ͖Δ࣌
  36. ద੾ʹϑΝΠϧΛ෼͚Δ ద੾ʹϑΝΠϧΛ౷߹͢Δ • ෼ׂ͢Δ࣌ • ໨త͕ҟͳΔ࣌: Ұൠతͳ΋ͷͱಛԽͨ͠΋ͷͰ෼͚Δɻ • ͦͷ୅ΘΓɺݺͼ෼͚ΔΑ͏ͳͷ͸ۃྗආ͚Δ •

  37. ϨΠϠ͝ͱʹந৅ԽΛม͑Δ • ϑΝΠϧγεςϜ • ௿ϨΠϠʹ͸HDDͷϒϩοΫ͕͋ͬͨΓɺσόΠευϥΠό͕ͦ ΕΛѻ͍ͬͯͨΓ͢Δ͕ɺߴϨΠϠͰ͸ͦΕΒΛҙࣝ͠ͳ͍Ͱѻ ͑ΔΑ͏ʹͳ͍ͬͯͨΓ͢Δɻ • ·ΕʹσʔλΛΩϟογϡ͢Δ૚΋͋ͬͨΓ͢Δɻ •

    ωοτϫʔΫɾϓϩτίϧ • TCP Ͱ৴པੑͷߴ͍ϓϩτίϧΛ࡞Γͭͭͦͷ্Ͱ͸ϨΠϠΛҙ ࣝ͠ͳ͍Α͏ʹͰ͖͍ͯΔ
  38. ϨΠϠ͝ͱʹந৅ԽΛม͑Δ • pass through ͸ආ͚Δ • pass through ݺͼग़ͨ͠ϝιου͕ผͳϝ ιουΛͨͩݺͿ͚ͩͷߦҝ

    • pass through ͸ϝιουΛ shallow ʹͯ͠ ͠·͏
  39. ྫ֎Λఆٛ͢Δ • ྫ֎Λग़͢΂͖͔ʁ͔Βߟ͑Δ • ྫ֎ΛҿΈࠐΉ࢓૊Έ • ͪΌΜͱྫ֎ΛͱυΩϡϝϯτʹ࢒͢

  40. ྫ֎Λग़͢΂͖͔ʁ͔Βߟ͑Δ • ྫ: Tcl ͰͷؒҧͬͨσβΠϯ • unset ͱ͍͏ม਺ͷத਎Λ࡟আ͢Δ࢓૊ΈΛݴޠʹೖΕͨʢGC͕ͳ͍͔Β ࢖ͬͨม਺Λ࡟আͯ͠΄͍࣌͠ͷ࢓૊Έʣ •

    ͨͩ͠ɺະఆٛͷม਺Λ unset ͨ͠৔߹͸ϓϩάϥϛϯάͷόάͱͯ͠ྫ֎ Λεϩʔ͢Δઃܭʹͯ͠͠·ͬͨɻ • ݁Ռͱͯ͠ɺͲͷม਺Λఆ͔ٛͨ͠ΛϓϩάϥϚʔ͕͍֮͑ͯͳ͍ͱ͍͚ͳ ͘ͳͬͯ͠·ͬͨɻ • catch Ͱશ෦ͬͯ͘͘ɺҰ୴ແࢹΈ͍ͨͳΞϯνύλʔϯ͕ੜ·Εͯ͠·ͬͨ
  41. ྫ֎Λग़͢΂͖͔ʁ͔Βߟ͑Δ • ྫ֎Λग़͞ͳ͍ઃܭ΋͋Δ • substring ϝιουʹ͍ͭͯߟ͑Δ • substring(start, end) Ͱ

    end < start ͩͬͨ࣌ʹྫ ֎Λεϩʔ͢Δ͔൱͔ʁ • Java ͸ྫ֎Λεϩʔ͢Δ͕ɺ Python ͸ۭͷจࣈ ྻΛฦ͢
  42. ྫ֎Λग़͢΂͖͔ʁ͔Βߟ͑Δ • Windows ͷϑΝΠϧγεςϜ͸࡟আର৅ͷϑΝΠ ϧ͕ಡࠐதͩͬͨ࣌ʹಡΈࠐΈ͕ऴΘΔ·Ͱ଴ͭ ͱ͍͏σβΠϯɺ݁Ռͱͯ͠γεςϜશମ͕ halt ͯ͠͠·͏ • Unix

    ͷϑΝΠϧγεςϜ͸ͦ͏Ͱ͸ͳ͘ɺϑΝΠ ϧΛҰ୴ಡΊΔ৔ॴʹ֬อ͔ͯ͠ΒಡΈࠐΈͱॻ ͖ग़͠͸ผ్ߦ͏
  43. ྫ֎ΛҿΈࠐΉ • TCP͸ଟগͭͳ͕Βͳ͔ͬͨΓɺྫ֎తͳঢ় گʹͳͬͨͱͯ͠΋ࣗ෼ͷதͰղܾ͢Δ • ϦτϥΠͨ͠ΓɺޡΓగਖ਼ͨ͠Γ͢Δ • ຊ౰ʹແཧͳঢ়گʹͳͬͨͱ͖͚ͩྫ֎Λ ্͛Δ

  44. ྫ֎ΛҿΈࠐΉ • ͜͏͍͏ͱ͖͸ຊ౰ʹྫ֎తͳঢ়گͰ͋Γɺ ͦͷͱ͖͸Ұ୴Ϋϥογϡͤͯ͞ϦΧόϦ͢ ΔͳΓɺͳΜͳΓͷରॲΛ্ҐϨΠϠʹٻΊ Δ

  45. ͪΌΜͱྫ֎ΛυΩϡϝϯτʹ ࢒͢ • ͲΜͳঢ়گͷྫ֎ͳͷ͔Λ໌ه͢Δ • Կ͕ॏཁͰԿ͕ॏཁͰͳ͍͔Λॻ͔ͳ͍ͱ͍͚ ͳ͍ • ॏཁ͡Όͳ͍ྫ֎͸Ӆͤͳ͍͔Λݕ౼͢Δ΂͖ •

    ॏཁͳྫ֎͸υΩϡϝϯτʹ໌ه͠ͳ͚Ε͹ͳ Βͳ͍
  46. design it twice

  47. ೋճઃܭ͠Ζ design it twice • ΤσΟλͷઃܭҰͭͱͬͯ΋ෳ਺ͷந৅Խͷઃܭ͕͋ΓಘΔ • ߦࢤ޲ͷΠϯλϑΣʔε • ྻࢤ޲ͷΠϯλϑΣʔε

    • จࣈྻࢤ޲ͷΠϯλϑΣʔε • ҰճͷઃܭͰ͢΂ͯͷϝϦοτͱσϝϦοτ͸Θ͔Βͳ͍ • ઃܭ͸ೋճͯ͠ΈΔʢ࣌ؒͷڐ͢ݶΓʣ
  48. ·ͱΊ • Tactical Programming ͸΍ΊΑ͏ • Strategic Programming Λਪ঑ •

    ෳࡶ͞͸ґଘͱᐆດ͔͞Βى͖Δ • ෳࡶ͞͸มߋ૿େɺೝ஌ෛՙɺΑ͘஌Βͳ͍͜ͱΛ૿Ճͤ͞Δ • Strategic Programming ͸͜ΕΒΛߟ͑௚ͨ͢ΊͷҰॿͱͳΔ΋ͷ • ౤ࢿϚΠϯυͰߟ͑ͯϓϩάϥϛϯά͢Δ