会社で優秀新人賞取った話

このエントリーをはてなブックマークに追加

10月の初めに所属部門のエンジニア評価制度で優秀新人賞取ったので、熱が冷めないうちに話しておこうかなと思います。

↓貰った賞の個人情報を切り抜いた画像です

まず、エンジニア評価制度についてですが、四半期ごとに事前に評価委員を決めて、四半期の最後にエンジニア同士で投票し合ってその投票結果を鑑みながら評価委員が受賞者を決めるという感じです。 自分はアプリ部(iOS/Androidアプリを作る部門の略称)に所属していて、30人ぐらい?の中から最優秀エンジニア賞・優秀エンジニア賞・優秀新人賞が配布されます。
そのうちの優秀新人賞を受賞したという感じです。

1Q(46月)は研修中で部門配属されてなくて評価対象外だったのですが、2Q(79月)は部門配属されてたので評価対象内となりました。というわけで、入賞という形なら部門最速記録をマークしたかなと思います。

そのあたりの細かい背景は今回の主旨ではないので省きます。

それで今回の言いたいことというのは部門内のKotlinコーディング規約を策定についていろいろと頑張ったこととその内容です。

Kotlinコーディング規約はJavaの影響を受けてた

よくあるKotlinコーディング規約やJetBrainsの規約はかなりJavaの影響を受けています。具体的にはconst valや右辺がコンパイル時定数となるobject valについてUPPER_SNAKE_CASEにしようというもの。

部門内に元からあったKotlinコーディング規約でもそのような命名規則になっていて、非常に無意味であり邪悪な存在でした。なぜ無意味で邪悪なのかについては以前に記事を書いたので参考にどうぞ。

定数にUPPER_SNAKE_CASEを使うのは辞めようっていう話

JavaやKotlinのコーディング規則ではよくコンパイル時定数や実質的に定数として扱っているものをUPPER_SNAKE_CASEとする命名規則が取られていますが、UPPER_SNAKE_CASEは致命的に読みにくいので辞めようっていう話です。

blog.meilcli.net

定数にUPPER_SNAKE_CASEを使うのは辞めようっていう話
Go to 定数にUPPER_SNAKE_CASEを使うのは辞めようっていう話

また理由が上記の記事で書いただけなら我慢すればいいという考えもできるのですが、Kotlinの場合問題となる書き方があります:

interface ITag {

    val tag: String
}

object Tag : ITag {

    override val tag: String = "tag"

    // overrideがなければその辺の規約ならばUPPER_SNAKE_CASEとなる
   val TAG: String = "tag"
}

右辺によって実質的に定数としてUPPER_SNAKE_CASEとする規則とinterfaceのメンバーの命名規則が衝突することがあります(そんなコード滅多にないですが)

規則の衝突はoverride修飾子がある場合はUPPER_SNAKE_CASEにしないみたいな特例を付ければ回避できますが、そんなことをするよりやっぱUPPER_SNAKE_CASEを滅ぼしたほうがシンプルでスマートだよな~~~ということで部門内で作成してたKotlinコーディング規約からは滅ぼしました。(やや反対意見があったのでJetBrainsの規約をほぼそのままに写したものも用意しましたが(部門内のKotlinコーディング規約がJetBrainsの規約ほぼそのままのと部門内で作成する2つに分裂した))

interfaceの命名規則一番マシなのはprefix Iなんじゃね?

classとinterfaceの名前が被ってどうしようということよくあると思うんですけど(よくあったらダメ)、そういう場合どうするか?という話です。

Javaでよくあるのはclass側が名前を譲って、interface Value / class ValueImplとするようにpostfix Impl classというのがあります。Javaの慣習に従順に従うならこれを問題視することはなかったかと思いますが、あいにく私はC#erなので、postfix Implを付けるclassと付けないclassが混在しているのは邪悪じゃね?という発想になりました。

これの代案はC#風にprefix I interfaceにするやpostfix Interface interfaceにするみたいなのがありましたが、どれも決定的な採用理由なんてありません。結局のところどれが一番マシなのかという話で、interfaceであることは確実にわかりたい情報ではないからclassと名前が被らなくなるだけに特化したprefix I interfaceを採用しました。(UPPER_SNALE_CASEの話と合わせて結構ゴリ押しした)

最終的なもの

型はUpperCamelCaseそれ以外はlowerCamelCaseという基本方針に加え、interfaceにはprefix Iを付けるなどの細微な追加規則がある命名規則になりました。(ついでにenum(ELEMENT)のUPPER_SNAKE_CASEも滅ぼした)
個人的には結構シンプルな命名規則になったんじゃないかなーと思います。

そのほかいろいろな規則を追加したりしましたが、細かいところはどうでもいいということで紹介は割愛です。

部門内で作成したKotlinコーディング規約はKotlinで書いたコードをJavaで利用するコードなんて書くことないだろうという前提で作成したので、Javaの気持ちを考えない規約にしましたが、そういうプロジェクトならUPPER_SNAKE_CASEを滅ぼしたりinterfaceにprefix Iを付けるようにするという選択肢はありよりのありかなと思います(布教)

そもそもinterfaceとclassの名前被るのは名前付けで甘えてない?って話

interfaceの役割って人によって認識が違うかもしれませんが、かねがね”機能”や”契約”といった表現で表されるかと思います。それに対してclassは”実装”とか”具象型”とか。

それらの名前が被るのは本来あっていいことなのかという議論も当然おきます。

運がいいことにそのあたりの熱い議論ができる新卒の同期がいたので、熱く議論を交わしましたが、コーディング規約として考えなければいけないのはどこまでの範囲かなど、コーディング規約の意味論まで行ってしまいました(議論は平行線をたどった)
ただ、名前が被らない証明をすることはできないというのは共通認識に取れた記憶があります(結構あいまい)

そういうわけもあり、prefix Iで甘えるんじゃねぇよという声が部門内からも聞こえてきてもおかしくはないですし、その声が多くなったらprefix Iは邪悪なので消そうという未来もあっていいとは思ってます。
それぐらい名前付けについて厳しい環境になればいいと思ってますが、そうなるまではC#erに優しいprefix Iで甘えま~~す、というお話でした~m(__)m