[Kotlin] underscore prefixに関するコーディング規約
目次
Kotlinのunderscore prefixに関するコーディング規約について書きます。
KotlinのCoding Conventions
Kotlin公式のCoding conventionsには、「If a class has two properties which are conceptually the same but one is part of a public API and another is an implementation detail, use an underscore as the prefix for the name of the private property」との記述があります。
つまり、外部にはinterfaceのみを公開し、privateなプロパティとしてその実装クラスのインスタンスを持っている場合です。この場合に、interfaceに対してunderscore prefix無しの名前を、実装クラスのインスタンスに対してunderscore prefix有りの名前をつけるとしています。
サンプルコードを以下に示します。 _awesomeStrings
が実装クラスのインスタンス、 awesomeStrings
がinterfaceです。interfaceに対してgetterを定義し、getterが実装クラスのインスタンスを返す、というKotlinでよく見る実装です。
class AwesomeClass {
private val _awesomeStrings = mutableListOf<String>()
val awesomeStrings: List<String> get() = _awesomeStrings
}
Kotlin公式のCoding Conventionsでは、上記のような場合に、privateプロパティにunderscore prefixを付けるとありました。他にはunderscore prefixに関する記述は見つけられませんでした。
AndroidのKotlin Style Guide
AndroidのKotlin style guideにも、同様の記述がありました。「When a backing property is needed, its name should exactly match that of the real property except prefixed with an underscore.」という記述があります。表現は異なりますが、指している内容は同等です。
こんな感じのサンプルコードが示されています。
private var _table: Map? = null
val table: Map
get() {
if (_table == null) {
_table = HashMap()
}
return _table ?: throw AssertionError()
}
Kotlin Design Patterns and Best Practices
ここからが本題です。Kotlin Design Patterns and Best Practices Second Edition (Soshin (2022))を読んでいたら、以下の記述を見つけました。
Using underscores for private variables is a common convention in Kotlin. (Soshin (2022)、P.59)
以下のようなコードを書く時に、 this.awesome = awesome
というような冗長なコードを書かなくて済むというメリットと、 awesome = awesome
と書いてしまうミスを無くすことができるメリットがある、と言うのですね。
class AnotherClass {
private var _awesome: AwesomeClass = AwesomeClass()
fun setAwesome(awesome: AwesomeClass) {
_awesome = awesome
}
}
そのメリットについてはよく理解できるのですが、Kotlinのcommon conventionだという認識はなかったのでちょっとびっくりしました。自分の調べた限りではKotlin公式のCoding conventionには上記のようなconventionは記載されておらず、common conventionなのかどうかは自分はわかりません。提示されているメリットについては理解できます。
一方で、この書き方は一種の(システム)ハンガリアン記法です。例えば「ハンガリアン記法は用いない」とするコーディング規約を設けているプロジェクトにおいてこういったunderscore prefixを付けることにした場合は、コーディング規約に例外が生まれることになります。
まあ、KotlinのCoding Conventionsの項で書いた以下の書き方を認める時点で、例外が生まれている感はありますが。
class AwesomeClass {
private val _awesomeStrings = mutableListOf<String>()
val awesomeStrings: List<String> get() = _awesomeStrings
}
そのあたりのメリット・デメリットをチームで話して、どの書き方は認めてどの書き方は認めない、ということを決めておくといいのかなと思いました。
Reference
- Coding conventions | Kotlin(最終アクセス日:2022年2月2日)
- Kotlin style guide | Android Developers(最終アクセス日:2022年2月2日)
- Kotlin Design Patterns and Best Practices Second Edition、Alexey Soshin(2022)、Packt Publishing
- ハンガリアン記法 - Wikipedia
書いている人 😎

茨城県つくば市在住のモバイルアプリケーションアーキテクト(Androidが得意です)。モバイルアプリのアーキテクチャ、自動テスト、CI/CDに興味があります。いわゆる「レガシーコード」のリファクタリング・リアーキテクチャが好きです。
👉 もっと詳しく
著書 ✍
Android 依存性注入 ヒッチハイク・ガイド🧳
Androidアプリでの依存性注入(Dependency Injection)に入門するためのガイダンスです。依存性注入の概念やメリットを理解し、Dagger Hiltを用いてAndroidアプリに適用する方法を解説しています。
ソフトウェアデザイン 2023年6月号📚
特集「クリーンアーキテクチャとは何か?」の第5章「モバイルアプリ開発における実践」を執筆しました。
Android クリーンアーキテクチャ ヒッチハイク・ガイド🧳
Androidアプリでのクリーンアーキテクチャに入門するためのガイダンスです。クリーンアーキテクチャの概念を理解し、Androidアプリに適用する方法を解説しています。
Android ユニットテスト ヒッチハイク・ガイド🧳
Androidアプリのユニットテストに入門するためのガイダンスです。初学者が混乱せずにAndroidアプリのユニットテストを書き始めることができる、ということを目的としています。
Android MVVMアーキテクチャ入門🛠
Androidアプリ開発の初学者に向けた、MVVM(Model-View-ViewModel)アーキテクチャの入門書を書きました。初学者の方を確実にネクストレベルに引き上げる技術書です。NextPublishingより出版されています。
関連記事 👀
- [Kotlin] 関数定義が1つだけのinterfaceは `fun interface` で定義できる
- ランチタイムLT会 #1で「何故、UseCaseは1メソッドなのか」というLTをしました
- DroidKaigi.collect{ #1@Tokyo }で「例外を投げるな、値を返せ」というLTをしました
- [Kotlin] 末尾カンマ
- [Kotlin] ifを愛でる