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

レビューのもやもや、なんとなく違うを浮き彫りに - 「読みやすいコードのガイドライン」の活用法

レビューのもやもや、なんとなく違うを浮き彫りに - 「読みやすいコードのガイドライン」の活用法

Munetoshi Ishikawa

April 14, 2023
Tweet

More Decks by Munetoshi Ishikawa

Other Decks in Programming

Transcript

  1. ॻ੶ʹ͍ͭͯ ಡΈ΍͍͢ίʔυͷΨΠυϥΠϯ - ࣋ଓՄೳͳιϑτ΢ΣΞ։ൃͷͨΊʹ - Oct. 22, 2022. ٕज़ධ࿦ࣾ -

    ϓϨθϯςʔγϣϯ ʮCode Readabilityʯ͕ϕʔε https://gihyo.jp/book/ 2022/978-4-297-13036-7
  2. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ /**ɹA collection of `Foo`, which provides ... */ class

    FooList(...) { /** True if this list is ordered. */ val ordered: Boolean get() { ... } /** Returns a new instance with reversed order */ fun reversed(): FooList { ... } /** Returns a new mutable `MutableFooList` from the elements. */ fun mutating(): MutableFooList { ... } }
  3. ࠓճͷ໰୊఺ จ๏: ಈࢺͷ෼ࢺ (...ing, ...ed) ΛҟͳΔҙຯʹ࢖͍ͬͯΔ val ordered: Boolean get()

    { ... } fun reversed(): FooList { ... } fun mutating(): MutableFooList { ... } - ordered: ৚݅Λຬ͍ͨͯ͠Δ͔Λਅِ஋Ͱࣔ͢ - reversed, mutating: ৚݅Λຬͨ͢৽ͨͳΠϯελϯεΛฦ͢
  4. ܗ༰ࢺɾ෼ࢺͷ࢖ΘΕํ ঢ়ଶ΍ੑ࣭Λࣔ͢஋ɾܕΛࣔ͢ - Iterable (Java/Kotlin), State.RUNNING ੑ࣭Λຬͨ͢ΠϯελϯεΛฦ͢ - sorted(iterable) (Python),

    Array.shuffled() (Swift) ੑ࣭Λຬ͍ͨͯ͠Δ͔Λਅِ஋Ͱࣔ͢ - val running: Boolean, fun sorted(): Boolean
  5. ࠓճͷϨϏϡʔίϝϯτྫ val ordered: Boolean get() { ... } fun reversed():

    FooList { ... } fun mutating(): MutableFooList { ... } > ໊લΛ࣍ͷΑ͏ʹมߋ͍ͯͩ͘͠͞: ordered -> isSorted, reversed -> toReversedList, mutating -> toMutableList > Kotlin Ͱ͸ɺ৽͍͠ΠϯελϯεΛฦ͢৔߹ʹ໋ྩจ͔෭ࢺΛ ࢖͍ɺਅِ஋Λࣔ͢৔߹ʹٙ໰จͳͲΛ࢖͍·͢ɻ
  6. ίϝϯτͷ෼ྨ υΩϡϝϯςʔγϣϯ: /** ... */ ౳ - ίʔυΛಡ·ͣʹ ཧղͤ͞Δίϝϯτ -

    ؔ਺΍Ϋϥεͷઆ໌ ඇܗࣜతͳίϝϯτ: ΠϯϥΠϯίϝϯτ // ... ౳ - ίʔυΛಡΈਐΊΔ ͜ͱΛॿ͚Δίϝϯτ - ཧ༝ɾഎܠɾ஫ҙ఺...ͦͷଞԿͰ΋
  7. ࠓճͷ໰୊఺ /** * Returns an empty string when the keyword

    is not registered. */ fun getDescription(keyword: String): String υΩϡϝϯςʔγϣϯͷ໾ׂΛՌ͍ͨͯ͠ͳ͍ - ʮ௨ৗʯԿΛ͢Δ͔͸Θ͔Βͳ͍ - Τοδέʔεʹ͍ͭͯ͸ॻ͔Ε͍ͯΔ
  8. ࠓճͷϨϏϡʔίϝϯτྫ > ࣍ͷΑ͏ͳυΩϡϝϯςʔγϣϯΛॻ͍͍ͯͩ͘͞ /** * Returns "description" of [keyword] if

    it's registered by * [registerDescription]. * * This returns an empty string when the keyword is not registered. */ > υΩϡϝϯςʔγϣϯͷ࠷ॳͷҰจͰɺͦͷؔ਺͕ԿΛ͢Δ͔ ΛҰݴͰઆ໌͢Δඞཁ͕͋Γ·͢ɻ
  9. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 1/2 fun getOnlineFollowers(userId: UserId): FollowerModelListResult { return FollowerModelListResult.Followers( if

    (!userId.isAlias) { followGraphRepository.getFollowers(userId) } else { val originalId = accountRepository.resolveAlias(userId) ?: return FollowerModelListResult.UnknownId followGraphRepository.getFollowers(originalId) }.filter { onlineStatusRepository.isOnline(it.userId) } .toSet() )}
  10. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 2/2 ϨϏϡʔΞ: getOnlineFollowers ͷॲཧ͕௥͍ʹ͍͘ͷͰɺϦϑΝ ΫλϦϯά͍ͯͩ͘͠͞ɻ ϨϏϡʔΠ: return FollowerModelListResult.Followers ͕࠷ॳ

    ʹ͋ΔͷͰɺ͜ͷؔ਺͕ԿΛ͢Δ͔͸໌֬ͩͱࢥ͍·͢ɻ ϨϏϡʔΠ: ·ͨɺҰͭͷࣜͱͯ͠ॻ͘͜ͱͰɺ FollowerModelListResult ͷऔಘҎ֎ʹ͸Կ΋͍ͯ͠ͳ͍͜ͱ΋ ໌֬ʹͳ͍ͬͯ·͢ɻ
  11. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 1/2 (࠶ܝ) fun getOnlineFollowers(userId: UserId): FollowerModelListResult { return FollowerModelListResult.Followers(

    if (!userId.isAlias) { followGraphRepository.getFollowers(userId) } else { val originalId = accountRepository.toOriginalId(userId) ?: return FollowerModelListResult.UnknownId followGraphRepository.getFollowers(originalId) }.filter { onlineStatusRepository.isOnline(it.userId) } .toSet() )}
  12. ࠓճͷϨϏϡʔίϝϯτྫ 1/4 > ҎԼͷิॿؔ਺Λఆ͍ٛͯͩ͘͠͞ɻ private fun resolveAlias(userId: UserId): UserId? =

    if (userId.isAlias) accountRepository.toOriginalId(userId) else userId > ͜ͷؔ਺Λ༻͍ͯɺgetOnlineFollowers ΛҎԼͷΑ͏ʹॻ͖׵ ͍͑ͯͩ͘͞ɻ
  13. ࠓճͷϨϏϡʔίϝϯτྫ 2/4 fun getOnlineFollowers(userId: UserId): FollowerModelListResult { val originalId =

    resolveAlias(userId) ?: return FollowerModelListResult.UnknownId val onlineFollowers = followGraphRepository.getFollowers(originalId) .filter { onlineStatusRepository.isOnline(it.userId) } .toSet() return FollowerModelListResult.Followers(onlineFollowers) }
  14. ࠓճͷϨϏϡʔίϝϯτྫ 3/4 > ฦ৴͍͍ͯͨͩͨ͠௨Γ Result ͷฦ٫͕͜ͷؔ਺ͷ࠷΋ॏཁͳ ఺Ͱ͋Δ͜ͱ͸͔֬Ͱ͢ɻ > ͔͠͠ɺͦΕࣗମ͸ؔ਺ͷγάωνϟ͔Β΋ಡΈऔΕ·͢ɻ >

    ؔ਺ΛಡΉࡍ͸ɺͦΕΑΓ΋Ұஈৄࡉͳ෦෼ͰʮԿΛ͍ͯ͠Δ ͔ʯ͕ཧղͰ͖Δඞཁ͕͋Γ·͢ɻ > ͜ͷؔ਺ͷྲྀΕ͸ɺҎԼͷΑ͏ʹͳ͍ͬͯ·͢ɻ
  15. ࠓճͷϨϏϡʔίϝϯτྫ 4/4 > 1. ඞཁͳΒ ID ͷΤΠϦΞεΛॲཧ͢Δ > 2. ϑΥϩΞʔΛऔಘ͠ɺΦϯϥΠϯͷ৚݅ͰϑΟϧλ͢Δ

    > 3. ϑΟϧλͷ݁ՌΛ Result ͱͯ͠ฦ͢ > ্هͷίʔυͰ͸ɺ͜ͷྲྀΕ͕໌֬ʹͳΔΑ͏ʹ͠·ͨ͠ɻ
  16. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 1/3 // // // class UserNameProvider { fun getName(userId:

    String): String = ... } class AccountScreenPresenter( val userNameProvider: UserNameProvider, ... ) { ... }
  17. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 2/3 interface StringProvider { fun getValue(parameter: String): String }

    class UserNameProvider : StringProvider { override fun getValue(parameter: String): String = ... } class AccountScreenPresenter( val userNameProvider: StringProvider, ... ) { ... }
  18. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 3/3 ϨϏϡʔΞ: StringProvider ͸ෆཁͳͷͰ࡟আ͍ͯͩ͘͠͞ɻ ϨϏϡʔΠ: ґଘؔ܎͸ऑ͘͢Δͷ͕޷·͍͠ͱݴΘΕ͍ͯ·͢ɻ ϨϏϡʔΠ: StringProvider Λఆٛ͢Δ͜ͱͰɺ

    UserNameProvider ʹର͢ΔґଘΛऑΊΔ͜ͱ͕Ͱ͖ΔͷͰɺ͜Ε ͸࢒͍ͨ͠Ͱ͢ɻ ϨϏϡʔΠ: ·ͨɺґଘੑͷٯసͷ๏ଇʹ΋Ԋͬͨઃܭʹͳ͍ͬͯ Δͱࢥ͍·͢ɻ
  19. ͲΜͳϨϏϡʔίϝϯτΛॻ͘ʁ 2/3 (࠶ܝ) interface StringProvider { fun getValue(parameter: String): String

    } class UserNameProvider : StringProvider { override fun getValue(parameter: String): String = ... } class AccountScreenPresenter( val userNameProvider: StringProvider, ... ) { ... }
  20. 6-5 ґଘͷ໌ࣔੑ - ໌ࣔతͳґଘ: Ϋϥεఆ͔ٛΒ ಡΈऔΕΔ ґଘؔ܎ - ҉໧తͳґଘ: ΫϥεఆٛͰ͸

    ಡΈऔΕͳ͍ ґଘؔ܎ ڧ͞ʢ݁߹౓ʣͱ໌ࣔੑ͸ผ - ऑ͍ && ໌ࣔతͳґଘؔ܎͕޷·͍͠ - ʮऑͨͭ͘͠΋Γ͕ɺ҉໧తʹͳ͚ͬͨͩʯΛආ͚Δ
  21. ࠓճͷϨϏϡʔίϝϯτྫ > StringProvider Λఆٛͯ͠΋ɺґଘͷڧ͞͸มΘΓ·ͤΜɻ > σʔλ݁߹ͱ͍͏ɺجຊతͳσʔλΛड͚౉͢͠Δڧ͞Ͱ͢ɻ > ҰํͰɺStringProvider ΛҾ਺ͷܕʹ͢Δ͜ͱͰɺ >

    UserNameProvider ΁ͷґଘ͕҉໧తʹͳ͍ͬͯ·͢ɻ > UserNameProvider ΠϯελϯεΛظ଴͍ͯ͠Δͷʹɺ > ࣮ࡍʹ͸ଞͷࢠΫϥεͷΠϯελϯε͕౉ͤͯ͠·͍·͢ɻ > ...