はじめに
- 私は、未経験エンジニアとして入社して新卒2年目になりました。普段Kotlinで開発をしています。自社にはJavaなどのコード規約はありますが、Kotlinのものはまだないのでそれを作っています。その中で普段開発する時に、よく使うKotlinの規約や書き方を後輩に聞かれることがあるので、特に新入社員向けにこの記事ではそれらをピックアップして書こうと思います。
なぜコード規約に従うのか
コード規約に従う理由について、下記などが挙げられると思います。
- 保守性、安全性、可読性、効率性、拡張性などの向上のため。
- gitでのチーム開発において、コンフリクトが起きにくくなるため。
命名規則
全般
- 基本的に文字列が長くても、役割が理解しやすい名前をつけることが好ましい。(補完があるので、長くても記述する際に面倒ではない。)
-
info
,data
,tmp
,アルファベット一文字は基本的に使わない。役割がわかりやすい名前にする。 - 理解できる程度に、名前を略すことは可能。
- 名前には英単語を使用し、日本語の単語をローマ字で記述しない。
- 大文字と小文字で名前を区別しない。
コレクション
リスト
- キャメルケース(ローワーキャメルケース)で宣言する。
- 複数形または、語尾に
List
をつけ宣言する。
参考: キャメルケースはローワーキャメルケース(先頭が小文字)、パスカルケースはアッパーキャメルケース(先頭が大文字)とも呼ばれる。それぞれ、単語ごとに大文字で区切る。
val users = listOf("Alice", "Bob", "Charlie") // 複数形
val userList = listOf("Alice", "Bob", "Charlie") // 語尾にList、キャメルケースで宣言
変数
- キャメルケース(ローワーキャメルケース)で宣言する。
val userCount = 10 // キャメルケースで宣言
関数
- キャメルケース(ローワーキャメルケース)で宣言する。
fun addNumbers(firstNumber: Int, secondNumber: Int): Int { // キャメルケースで宣言
return firstNumber + secondNumber
}
クラス・インターフェイス
- パスカルケース(アッパーキャメルケース)で宣言する。
// クラスの例
class Employee(val name: String, val position: String) // パスカルケースで宣言
// インターフェースの例
interface Shape { // パスカルケースで宣言
fun calculateArea(): Double
}
ファイル
- パスカルケース(アッパーキャメルケース)で宣言する。
- クラスを定義しているファイルは、クラス名とファイル名は同じにする。
パッケージ
- 全て小文字。
型宣言
- 極力、
Non-Null
で型を宣言する。 - 極力、
var
を使わない。 - 極力、非nullアサーション演算子(
!!
)は使わない。 - 極力、コレクションで、mutableは使わない。
- コレクションの要素が、何もない場合は、
null
ではなく、emptyList()
を入れる。そのため、コレクションをNullable
な型で宣言しない。 - Kotlinは型推論があるので、基本的には宣言する際に型は省略する。
// 型推論で宣言
val title = "タイトル" // Stringであることを明示的に宣言しない。
フォーマット
-
基本的にIntelliJ IDEAのフォーマッタに従う。
- ショートカットキー(Mac):
option
+command
+L
- ショートカットキー(Windows):
Ctrl
+Alt
+L
- メニューバーの
Code
からReformat Code
を選択。
- ショートカットキー(Mac):
-
使っていない
import
は残してはいけない。IntelliJ IDEAでは下記のやり方で使っていないimport
を一括で削除できる。- ショートカットキー(Mac):
option
+control
+O
- ショートカットキー(Windows):
Ctrl
+Alt
+O
- メニューバーの
Code
からOptimize Imports
を選択。
- ショートカットキー(Mac):
-
インデントは、4つのスペース。
-
空白の行は、空白。スペースやタブを入れてはいけない。
-
行がスペースやタブで終わってはいけない。
-
行末以外は、コンマの後にスペースを入れる。
-
演算子の前後はスペースを入れる。
-
ファイルの末尾は、改行を一つ入れる。
-
一行に120文字を超える場合は適当に改行する。
-
未実装の部分は、
TODO()
を入れる。
関数
- 関数はデフォルトで他のクラスからアクセスすることができるパブリック関数になっているので、他クラスからアクセスされることがない関数は、安全のために
private
修飾子をつけ、他クラスからアクセスされないようにする。- ただ、プライペートな関数の単体テストをする場合、対象の関数がプライベート関数であるとテストのためにアクセスすることができない。その場合は、同じモジュール内からアクセスすることができるインターナル関数にするために、
private
修飾子をinternal
修飾子に変更しても良い。
- ただ、プライペートな関数の単体テストをする場合、対象の関数がプライベート関数であるとテストのためにアクセスすることができない。その場合は、同じモジュール内からアクセスすることができるインターナル関数にするために、
- 関数呼び出し側は極力引数名を記述すること。
コメント
- コメントアウトしたプログラムの断片を次工程まで放置しない。
- できるだけわかりやすく書くこと。ただ、コメントがなくても理解できるコードが好ましい。
- 英語または日本語で書く。
クラス
- 基本的には、一つのファイルにつきクラスは一つ。
テスト
- テスト関数には、
DsiplayName()
をつけて、何をテストしているのかわかりやすくする。
コードを書く際に気を付けていること
入社して、1年とちょっとたったので、未経験時代と比べて振り返り、書き方が変わった、学んだことをあげます。
-
for
文は基本的に使わない。コレクションのメソッドのforEach
を使う。 - Kotlinは
if
文ではなく、if
式なので、変数に代入することができる。 - コレクションの処理は、コレクションのメソッドを有効活用する。
- DDDで開発する際に、Infrastructureとdomainのクラスの名前が、Infrastructureのファイル内で名前が同じだったら、Infrastructureの方のクラス名をを
as
で名前を変える。 - データを保持するクラスには、
data class
を使う。 - ループ処理のネストはできるだけ少なくする。ループ処理の中で、
return@xxx
のように、ラベル付きリターンはを使わない。 - JavaのメソッドにKotlinのクラスを入れたいときは、::java.classをつけることで、入れることができる。
- lambdaを利用する際は複数形→単数形の変数名で展開する。例:
items.map { item -> ... }
終わりに
- 自分なりの書き方をするよりも、コード規則などの統一した書き方に従うことで、初めはストレスを感じることがありました。ですが、慣れてくると決まった書き方に従うことで、むしろ助けられることが多いことに気づきました。
- 入社して1年とちょっと経ち、先輩方からより良いプログラムの書き方を学び、入社時と比べると確実に良くはなっている自覚はあります。ですが、まだまだ未熟ですのでより良いプログラムを書けるようにこれからも精進していきたいです。