Upgrade to Pro — share decks privately, control downloads, hide ads and more …

読みやすいコードの書き方 第 1 回 / Code readability: Session 1 (ver. 2, Ja)

読みやすいコードの書き方 第 1 回 / Code readability: Session 1 (ver. 2, Ja)

第 1 回: 導入と原則

---

セッションリスト

第 1 回: 導入と原則
- https://speakerdeck.com/munetoshi/code-readability-session-1-ver-2-ja

第 2 回: 命名
- https://speakerdeck.com/munetoshi/code-readability-session-2-ver-2-ja

第 3 回: コメント
- https://speakerdeck.com/munetoshi/code-readability-session-3-ver-2-ja

第 4 回: 状態
- https://speakerdeck.com/munetoshi/code-readability-session-4-ver-2-ja

第 5 回: 関数
- https://speakerdeck.com/munetoshi/code-readability-session-5-ver-2-ja

第 6 回: 依存関係 I
- https://speakerdeck.com/munetoshi/code-readability-session-6-ver-2-ja

第 7 回: 依存関係 II
- https://speakerdeck.com/munetoshi/code-readability-session-7-ver-2-ja

第 8 回: レビュー
- https://speakerdeck.com/munetoshi/code-readability-session-8-ver-2-ja

---

関連書籍 「読みやすいコードのガイドライン - 持続可能なソフトウェア開発のために」
- https://gihyo.jp/book/2022/978-4-297-13036-7

英語版のリスト: https://gist.github.com/munetoshi/65a1b563fb2c271f328c121a4ac63571#file-code-readability-links-md

以前のバージョン (英語): https://speakerdeck.com/munetoshi/code-readability

© 2019-2023 Munetoshi Ishikawa, supported by LINE corporation

Munetoshi Ishikawa

May 11, 2023
Tweet

More Decks by Munetoshi Ishikawa

Other Decks in Programming

Transcript

  1. ಡΈ΍͍͢ίʔυͷཁ݅ - ໌֬: flag ΑΓ isVisible - ୯७: !(!isA ||

    !isB) && isB ΑΓ isA && isB - ಠཱੑ͕ߴ͍: ؔ਺, Ϋϥε, Ϟδϡʔϧ... - ߏ଄త: ϑΥʔϚοτ, ґଘؔ܎, ঢ়ଶભҠ... ҰͭͷࢦඪͰ͸ಡΈ΍͢͞ΛଌΕͳ͍ ʮԿ͕ಡΈ΍͍͔͢ʯ͸࣌୅ͱίϯςΩετʹґଘ͢Δ ಋೖͱݪଇ > ಋೖ
  2. ՄಡੑΛߴΊΔऔΓ૊Έํ - ஌ࣝ΍ٕज़Λબ୒͢Δ ʢ࢖͏໨తΛݟࣦΘͳ͍ʣ - Ձ஋ͱෳࡶ͞ͷόϥϯε ΛऔΔ - ࣗಈతͳݕূ Λ׆༻͢Δ

    ʢίϯύΠϥ, ςετ, etc.ʣ - ٞ࿦Λසൟʹߦ͏ ʢϛεͷख໭ΓΛখ͘͢͞Δʣ - ܧଓֶͯ͠श͢Δ ಋೖͱݪଇ > ಋೖ
  3. ߨٛͷߏ੒ - ಋೖͱݪଇ - ࣗવݴޠ: ໋໊, ίϝϯτ - ܕͷߏ଄: ঢ়ଶ,

    ؔ਺ - ܕؒͷߏ଄: ґଘؔ܎I, ґଘؔ܎II - ϨϏϡʔ ಋೖͱݪଇ > ಋೖ
  4. ߨٛͷߏ੒ - ಋೖͱݪଇ - ࣗવݴޠ: ໋໊, ίϝϯτ - ܕͷߏ଄: ঢ়ଶ,

    ؔ਺ - ܕؒͷߏ଄: ґଘؔ܎I, ґଘؔ܎II - ϨϏϡʔ ಋೖͱݪଇ > ಋೖ
  5. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ
  6. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ
  7. ϘʔΠεΧ΢τϧʔϧ Try to leave this world a little better than

    you found it... — Robert Baden-Powell Robert C. Martin ͕ιϑτ΢ΣΞ։ൃʹద༻1 ίʔυʹมߋΛՃ͑Δͱ͖ɺվળΛࢪ͢ 1 97 Things Every Programmer Should Know: Collective Wisdom from the Experts, Kevlin Henney, 2010 ಋೖͱݪଇ > ݪଇ > ϘʔΠεΧ΢τϧʔϧ
  8. ϘʔΠεΧ΢τϧʔϧͰ͢΂͖͜ͱ 1/2 - ௥Ճ: ίϝϯτ, ςετ - ࡟আ: ෆཁͳґଘؔ܎, ϝϯό,

    ঢ়ଶ - ໊લͷมߋ: Ϋϥε, ؔ਺, ม਺ - ෼ׂ: ڊେͳΫϥε, ؔ਺, ωετ, ݺͼग़ؔ͠܎ - ߏ଄Խ: ϑΥʔϚοτ, ґଘؔ܎, ந৅ԽϨΠϠ, ܧঝ֊૚ ಋೖͱݪଇ > ݪଇ > ϘʔΠεΧ΢τϧʔϧ
  9. ϘʔΠεΧ΢τϧʔϧͷద༻ྫ 1/3 ໰୊: ৽͍͠ ViewType ͱͯ͠ Z Λ௥Ճͯ͠Α͍ʁ val viewType:

    ViewType = ... // An enum type when (viewType) { A -> { view1.isVisible = true view2.text = "Case A" } B -> { view1.isVisible = false view2.text = "Case B" } ... ಋೖͱݪଇ > ݪଇ > ϘʔΠεΧ΢τϧʔϧ
  10. ϘʔΠεΧ΢τϧʔϧͷద༻ྫ 3/3 1: ϓϩύςΟͱͯ͠ நग़͢Δ enum class ViewType(val isView1Visible: Boolean,

    val view2Text: String) 2: ϓϩύςΟΛ࢖ͬͯ ৚݅෼ذΛ࡟আ͢Δ view1.isVisible = viewType.isView1Visible view2.text = viewType.view2Text 3: ৽͍͠λΠϓ Z Λ௥Ճ͢Δ ಋೖͱݪଇ > ݪଇ > ϘʔΠεΧ΢τϧʔϧ
  11. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ
  12. YAGNI You Aren't Gonna Need It ඞཁͳͱ͖͚࣮ͩ૷͢Δ - ʮকདྷͷͨΊʯͷػೳͷ 90%

    ͸࢖ΘΕͳ͍ 2 - ߏ଄Λ୯७ʹอͭ = ࢓༷มߋʹରԠ͠΍͍͢ 2 2 http://www.extremeprogramming.org/rules/early.html ಋೖͱݪଇ > ݪଇ > YAGNI
  13. YAGNI ʹҧ൓͍ͯ͠Δྫ UI ཁૉͷ࠲ඪΫϥεʹʮ୯ҐʯΛ௥Ճ͢Δ class Coordinate(val x: Int, val y:

    Int, val unitType: UnitType) enum class UnitType { PIXEL, POINT } Coordinate + Coordinate Λఆٛ͠Α͏ͱ͢Δͱෳࡶʹ ࢖ΘΕ͍ͯͳ͍ػೳͷ࣮૷͸ؒҧͬͨઃܭΛҾ͖ى͜͠΍͍͢ ಋೖͱݪଇ > ݪଇ > YAGNI
  14. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ
  15. KISS Keep It Simple Stupid — Clarence Leonard "Kelly" Johnson

    ୯७ͳํ๏ΛબͿ - ՄೳͳݶΓඪ४ͷ࣮૷Λ࢖͏ - ϥΠϒϥϦɾϑϨʔϜϫʔΫɾσβΠϯͷ༻్ΛߜΔ ඒ͍͠ɾ༏խͳίʔυ͕ಡΈ΍͍͢ͱ͸ݶΒͳ͍ ಋೖͱݪଇ > ݪଇ > KISS
  16. KISS: Α͘ͳ͍ྫ return userActionLog .groupBy { it.user } .map {

    it.key to it.value.size } .sortedBy { it.second } .map { it.first } .takeLast(10) Ϩγʔό΍ it ͕Կ͔͸ ͢΂ͯಡ·ͳ͍ͱཧղ͕Ͱ͖ͳ͍ ಋೖͱݪଇ > ݪଇ > KISS
  17. KISS: Α͘ͳ͍ྫ return userActionLog .groupBy ... .map ... .sortedBy ...

    .map ... .takeLast(10) Ϩγʔό΍ it ͕Կ͔͸ ͢΂ͯಡ·ͳ͍ͱཧղ͕Ͱ͖ͳ͍ ಋೖͱݪଇ > ݪଇ > KISS
  18. KISS: Α͍ྫ val logCountByUser: Map<User, Int> = userActionLog .groupBy {

    log -> log.user } .map { (user, logs) -> user to logs.size } val userListSortedByLogCount: List<User> = logCountByUser .sortedBy { (_, messageCount) -> messageCount } .map { (userId, _) -> userId } return userListSortedByLogCount.takeLast(10) ඒ͘͠͸ͳ͍͕ɺཧղ͠΍͍͢ ಋೖͱݪଇ > ݪଇ > KISS
  19. KISS: Α͍ྫ val logCountByUser: Map<User, Int> = userActionLog ... ...

    val userListSortedByLogCount: List<User> = logCountByUser ... ... return userListSortedByLogCount.takeLast(10) ඒ͘͠͸ͳ͍͕ɺཧղ͠΍͍͢ ಋೖͱݪଇ > ݪଇ > KISS
  20. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ > ୯Ұ੹೚ݪଇ
  21. ୯Ұϝιου == ୯Ұ੹೚ʁ ϝιουͷ਺Ͱ͸੹೚͸ଌΕͳ͍ class Alviss { // May show

    a text, may break the device, may launch a rocket, // may ... fun doEverything(state: UniverseState) } ಋೖͱݪଇ > ݪଇ > ୯Ұ੹೚ݪଇ
  22. ୯Ұ੹೚ݪଇ A class should have only one reason to change.

    — Robert C. Martin ̎ͭҎ্ͷػೳΛࠞͥͯ͸͍͚ͳ͍ ಋೖͱݪଇ > ݪଇ > ୯Ұ੹೚ݪଇ
  23. ୯Ұ੹೚ݪଇ: Α͘ͳ͍ྫ 2/2 class LibraryBookRentalData( val bookIds: MutableList<Int>, val bookNames:

    MutableList<String>, val bookIdToRenterNameMap: MutableMap<Int, String>, val bookIdToDueDateMap: MutableMap<Int, Date>, ... ) { fun findRenterName(bookName: String): String? fun findDueDate(bookName: String): Date? ... ಋೖͱݪଇ > ݪଇ > ୯Ұ੹೚ݪଇ
  24. ୯Ұ੹೚ݪଇ: վળҊ 2/2 data class BookData(val id: Int, val name:

    String, ...) data class UserData(val name: String, ...) class CirculationRecord( val onLoanBookEntries: MutableMap<BookData, Entry> ) { data class Entry(val renter: UserData, val dueDate: Date) ಋೖͱݪଇ > ݪଇ > ୯Ұ੹೚ݪଇ
  25. ࠓճͷ಺༰ - ಋೖ - ϘʔΠεΧ΢τϧʔϧ - YAGNIɹ - KISSɹ -

    ୯Ұ੹೚ݪଇ - ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ ಋೖͱݪଇ > ݪଇ
  26. ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ 1/2 We should forget about small efficiencies, say about

    97% of the time: premature optimization is the root of all evil. — Structured Programming with go to Statements, Donald Knuth ಋೖͱݪଇ > ݪଇ > ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ
  27. Α͍࠷దԽͷྫ ࠷దԽલ: val data = arrayList.find { data -> data.key

    == expectedKey } ࠷దԽޙ: val data = hashMap[expectedKey] ίʔυΛ୯७ʹͭͭ͠ ܭࢉྔΛݮΒ͢ ಋೖͱݪଇ > ݪଇ > ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ
  28. ίʔυΛෳࡶʹ͢Δ࠷దԽ 1/2 Yet we should not pass up our opportunities

    in that critical 3% — Donald Knuth ಋೖͱݪଇ > ݪଇ > ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ
  29. ίʔυΛෳࡶʹ͢Δ࠷దԽ 1/2 - ՄมΦϒδΣΫτͷ࠶ར༻ - Πϯελϯεϓʔϧ - ஗ԆॳظԽ - Ωϟογϡ

    ϓϥοτϑΥʔϜͷαϙʔτ͔ϓϩϑΝΠϦϯά͕ඞཁ ಋೖͱݪଇ > ݪଇ > ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ
  30. ࠷దԽͷฐ֐ ୯७Խͷ๦͛ʹͳΔ - ΦϓςΟϚΠβͷ΄͏͕ੑೳ͕Α͍͜ͱ΋ Φʔόϔουίετ͕͔͔Δ - Ωϟογϡ: Ωϟογϡϛε཰ ΞΫηε࣌ؒ -

    ஗ԆॳظԽ: (ಉظతͳ) ΠϯελϯενΣοΫ ಋೖͱݪଇ > ݪଇ > ࣌ظঘૣͳ࠷దԽ͸ॾѱͷࠜݯ
  31. ·ͱΊ ಡΈ΍͍͢ίʔυ: ੜ࢈ੑΛҡ࣋͢Δखஈ ϘʔΠεΧ΢τϧʔϧ: ίʔυมߋલΑΓಡΈ΍͘͢ YAGNI: ඞཁʹͳͬͨͱ͖ʹॳΊ࣮ͯ૷ KISS: ୯७ͳํ๏Λ࢖͏, ඒ͍͠

    != ಡΈ΍͍͢ ୯Ұ੹೚ݪଇ: ੹೚ൣғΛ໌֬ʹ ࣌ظঘૣͳ࠷దԽ: ࠷దԽͷલʹϓϩϑΝΠϦϯάɾݟੵ΋Γ ಋೖͱݪଇ > ·ͱΊ