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

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

330

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

第 8 回: レビュー

---

セッションリスト

第 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

Transcript

  1. ߨٛͷߏ੒ - ಋೖͱݪଇ - ࣗવݴޠ: ໋໊, ίϝϯτ - ܕͷߏ଄: ঢ়ଶ,

    ؔ਺ - ܕؒͷߏ଄: ґଘؔ܎I, ґଘؔ܎II - ϨϏϡʔ ίʔυϨϏϡʔ > ಋೖ
  2. τοϓμ΢ϯํࣜ ߏ଄͚ͩΛ࡞ΓɺޙͰ࣮૷ΛຒΊΔ 1. ߏ଄Λઆ໌͢ΔͨΊͷεέϧτϯΫϥεΛ࡞Δ 2. ࠓޙͷϓϥϯΛ TODO ΍ϓϧϦΫΤετͷίϝϯτͰઆ໌͢Δ class UserProfilePresenter(

    val userProfileUseCase: UseCase val profileRootView: View ) { fun showProfileImage() = TODO("#12345: ...") ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > େ͖ͳػೳ࣮૷࣌
  3. ϘτϜΞοϓํࣜ ෦඼Λઌʹ࡞Δ 1. ʮ࢖͏ଆʯ͕ͳ͍ঢ়ଶͰ୯७ͳΫϥεɾؔ਺Λ࣮૷͢Δ 2. কདྷͲ͏࢖͏͔Λ TODO ΍ϓϧϦΫΤετͷίϝϯτͰઆ໌͢Δ data class

    UserProfileData(val ..., val ...) // TODO(#12346): ... object UserNameStringUtils { @Suppress("unused") // TODO(#12347): ... fun normalizeEmoji(userName: String): String = ... ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > େ͖ͳػೳ࣮૷࣌
  4. ௥Ճ࡞ۀͷൃੜྫ 1/3 લఏ 1: ࣌ࠁදࣔͷػೳΛ࣮૷ class CurrentClockIndicator(...) { fun showCurrentTime()

    { val clockText = toClockText(...) // ... } companion object { private fun toClockText(...: Long): String = ... } } ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  5. ௥Ճ࡞ۀͷൃੜྫ 2/3 ࣮૷࣌ͷίϛοτϦετ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 2: ϓϥΠϕʔτϢʔςΟϦςΟؔ਺

    `toClockText` ࣮૷ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  6. ௥Ճ࡞ۀͷൃੜྫ 3/3 લఏ 2: toClockText ͷίϐʔ͕طଘΫϥεʹ͋Δ͜ͱ͕ൃ֮ DateTimeTextFormatter ͱͯ͠ڞ௨ίʔυΛநग़͍ͨ͠ object DateTimeTextFormatter

    { fun toClockText(...: Long): String = ... } class CurrentClockIndicator(...) { fun showCurrentTime() { val clockText = DateTimeTextFormatter.toClockText(...) // ... ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  7. ௥Ճ࡞ۀͷϓϧϦΫΤετͷऔΓѻ͍ ໰୊: ͲͷΑ͏ͳϓϧϦΫΤετΛ࡞੒͢Ε͹Α͍͔ - Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ - Ξϯνύλʔϯ 2:

    ࣌ܥྻͰϓϧϦΫΤετΛ෼ׂ - ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ - ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  8. ௥Ճ࡞ۀͷϓϧϦΫΤετͷऔΓѻ͍ ໰୊: ͲͷΑ͏ͳϓϧϦΫΤετΛ࡞੒͢Ε͹Α͍͔ - Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ - Ξϯνύλʔϯ 2:

    ࣌ܥྻͰϓϧϦΫΤετΛ෼ׂ - ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ - ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  9. Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ ϓϧϦΫΤετͷίϛοτ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 2:

    ϓϥΠϕʔτϢʔςΟϦςΟؔ਺ `toClockText` ࣮૷ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ Commit 4: `toClockText` Λ `DateTimeTextFormatter` ͱͯ͠நग़ Commit 4 ͷ໾ׂ͕ҟͳΔ && มߋ͕ڊେʹͳΔ ʮநग़࿙Ε͕ͳ͍͔ʯͳͲͷ֬ೝࣄ߲͕૿͑Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  10. ௥Ճ࡞ۀͷϓϧϦΫΤετͷऔΓѻ͍ ໰୊: ͲͷΑ͏ͳϓϧϦΫΤετΛ࡞੒͢Ε͹Α͍͔ - Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ - Ξϯνύλʔϯ 2:

    ࣌ܥྻͰϓϧϦΫΤετΛ෼ׂ͢Δ - ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ - ղܾҊ 2: ίϛοτΛ෼ׂɾฒ΂ସ͑ɾ౷߹͢Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  11. Ξϯνύλʔϯ 2: ࣌ܥྻͰ෼ׂ͢Δ 1/2 ϓϧϦΫΤετ A ͷίϛοτ Commit 1: `CurrentTimeIndicator`

    ͷεέϧτϯΫϥε࡞੒ Commit 2: ϓϥΠϕʔτϢʔςΟϦςΟؔ਺ `toClockText` ࣮૷ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ϓϧϦΫΤετ B ͷίϛοτ Commit 4: `toClockText` Λ `DateTimeTextFormatter` ͱͯ͠நग़ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  12. Ξϯνύλʔϯ 2: ࣌ܥྻͰ෼ׂ͢Δ 2/2 ϓϧϦΫΤετ A ͷϚʔδޙʹ ϓϧϦΫΤετ B ΛϚʔδ

    ٕज़తෛ࠴Λট͘ - Ұ࣌తʹίʔυͷίϐʔ͕ߦΘΕΔ - ࡞ۀͷׂΓࠐΈ౳Ͱ ϓϧϦΫΤετ B ͕์ஔ͞Εͯ͠·͏ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  13. ௥Ճ࡞ۀͷϓϧϦΫΤετͷऔΓѻ͍ ໰୊: ͲͷΑ͏ͳϓϧϦΫΤετΛ࡞੒͢Ε͹Α͍͔ - Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ - Ξϯνύλʔϯ 2:

    ࣌ܥྻͰϓϧϦΫΤετΛ෼ׂ͢Δ - ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ - ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  14. ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ 1/2 ฒߦͯ͠ DateTimeTextFormatter ͷϓϧϦΫΤετΛ࡞Δ ద༻৚݅: toClockText ࣮૷લʹίʔυͷॏෳʹؾ͕͍ͭ৔߹

    ϓϧϦΫΤετ A ͷίϛοτ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ ϓϧϦΫΤετ B ͷίϛοτ Commit 4: `toClockText` Λ `DateTimeTextFormatter` ͱͯ͠நग़ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  15. ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ 2/2 ϓϧϦΫΤετ B ͷϚʔδޙ ϓϧϦΫΤετ A ΛϦϕʔε

    நग़ޙͷ toClockText Λ࢖ͬͯϓϧϦΫΤετ A Λ࡞੒Մೳ ϓϧϦΫΤετ A ͷίϛοτ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  16. ௥Ճ࡞ۀͷϓϧϦΫΤετͷऔΓѻ͍ ໰୊: ͲͷΑ͏ͳϓϧϦΫΤετΛ࡞੒͢Ε͹Α͍͔ - Ξϯνύλʔϯ 1: 1ͭͷϓϧϦΫΤετʹ·ͱΊΔ - Ξϯνύλʔϯ 2:

    ࣌ܥྻͰϓϧϦΫΤετΛ෼ׂ͢Δ - ղܾҊ 1: ௥Ճ࡞ۀΛઌʹ׬ྃͤ͞Δ - ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  17. ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ 1/4 Step 1: Commit 4 Λ෼ׂ Commit

    1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 2: ϓϥΠϕʔτϢʔςΟϦςΟؔ਺ `toClockText` ࣮૷ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ Commit 4_EXISTING: طଘίʔυͷ `toClockText` Λநग़ Commit 4_NEW: `CurrentTimeIndicator` ͷ `toClockText` Λநग़ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  18. ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ 1/4 Step 2: ίϛοτΛฒ΂ସ͑Δ Commit 4_EXISTING: طଘίʔυͷ

    `toClockText` Λநग़ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 2: ϓϥΠϕʔτϢʔςΟϦςΟؔ਺ `toClockText` ࣮૷ Commit 4_NEW: `CurrentTimeIndicator` ͷ `toClockText` Λநग़ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  19. ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ 1/4 Step 3: த 3 ͭͷίϛοτΛ౷߹͢Δ Commit

    4_EXISTING: طଘίʔυͷ `toClockText` Λநग़ Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ --squashed--ɹ --squashed--ɹ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  20. ղܾҊ 2: ίϛοτΛ࠶ߏ੒͢Δ 1/4 Step 4: 2 ͭͷϓϧϦΫΤετΛ࡞੒͢Δ ϓϧϦΫΤετ B

    Commit 4_EXISTING: طଘίʔυͷ `toClockText` Λநग़ ϓϧϦΫΤετ A Commit 1: `CurrentTimeIndicator` ͷεέϧτϯΫϥε࡞੒ Commit 3: `CurrentTimeIndicator` ͷ `showCurrentTime` ࣮૷ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > খ͍͞ϓϧϦΫΤετ > ௥Ճ࡞ۀʹର͢ΔରԠ
  21. ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ: ·ͱΊ ϓϧϦΫΤετͷ੹೚ൣғΛ໌ࣔ͢Δ - ओͳ໨తɾୡ੒͍ͨ͜͠ͱ - ߦΘͳ͍͜ͱɾࠓޙͷܭը ϓϧϦΫΤετΛখ͘͢͞Δ - େ͖ͳػೳ࣮૷࣌:

    τοϓμ΢ϯɾϘτϜΞοϓ - ௥Ճ࡞ۀ࣌: ฒྻ࡞ۀɾίϛοτͷ࠶ߏ੒ ίʔυϨϏϡʔ > ϨϏϡʔ͠΍͍͢ϓϧϦΫΤετ > ·ͱΊ
  22. ϨϏϡʔϦΫΤετ΁ͷରԠ Α͍: - ظݶ಺ʹϨϏϡʔ͢Δ - ଞͷਓʹϦμΠϨΫτ͢Δ - ʮϨϏϡʔ͕೉͍͠ʯ ͱฦ৴͢Δ ͋·ΓΑ͘ͳ͍:

    ϨϏϡʔϦΫΤετΛແࢹ͢Δ ͔ͳΓΑ͘ͳ͍: ʮϨϏϡʔ͢Δʯͱݴ࣮ͬͯࡍʹ͸ϨϏϡʔ͠ͳ͍ ίʔυϨϏϡʔ > ϨϏϡʔΞͷݪଇ > ແࢹ͠ͳ͍
  23. ίϝϯτͷέʔεελσΟ ؔ਺ʹԾҾ਺Λ௥Ճ͢Δྫ fun showPhotoView( photoData: PhotoData, isInEditScreen: Boolean ) {

    if (!photoData.isValid) { if (isInEditScreen) { showDialog() } return } ... ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  24. ίϝϯτͷέʔεελσΟ ໋໊: ʮͲ͜Ͱʯݺ͹ΕΔ͔ΑΓ΋ʮԿΛ͢Δ͔ʯΛઆ໌͢Δ fun showPhotoView( photoData: PhotoData, isInEditScreen: Boolean )

    { if (!photoData.isValid) { if (isInEditScreen) { showDialog() } return } ... ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  25. ίϝϯτͷέʔεελσΟ ໋໊: ʮͲ͜Ͱʯݺ͹ΕΔ͔ΑΓ΋ʮԿΛ͢Δ͔ʯΛઆ໌͢Δ fun showPhotoView( photoData: PhotoData, showsDialogOnError: Boolean )

    { if (!photoData.isValid) { if (showsDialogOnError) { showDialog() } return } ... ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  26. ίϝϯτͷέʔεελσΟ ґଘؔ܎: ਅِ஋ʹΑΔ੍ޚ݁߹Λղফ͢Δ fun showPhotoView( photoData: PhotoData, showsDialogOnError: Boolean )

    { if (!photoData.isValid) { if (showsDialogOnError) { showDialog() } return } ... ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  27. ίϝϯτͷέʔεελσΟ ґଘؔ܎: ਅِ஋ʹΑΔ੍ޚ݁߹Λղফ͢Δ fun showPhotoView( photoData: PhotoData ): Boolean {

    if (!photoData.isValid) { return false } ... ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  28. ίϝϯτͷέʔεελσΟ ґଘؔ܎: ਅِ஋ʹΑΔ੍ޚ݁߹Λղফ͢Δ ฤूը໘: val isViewShown = showPhotoView(...) if (!isViewShown)

    { showErrorDialog(...) } ͦΕҎ֎ͷը໘: showPhotoView(...) ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ
  29. ίϝϯτͷέʔεελσΟ ίϝϯτ: ؔ਺໊͕໭Γ஋Λઆ໌͍ͯ͠ͳ͍৔߹ɺίϝϯτΛॻ͘ /** * Shows a photo at the

    center if the given photo data is ..., * and returns true. * Otherwise, this returns false without showing the view. */ fun showPhotoView(photoData: PhotoData): Boolean { if (!photoData.isValid) { return false } ίʔυϨϏϡʔ > ίϝϯτͷ಺༰ > έʔεελσΟ