Help us understand the problem. What is going on with this article?

Kotlinで@Deprecatedと@Experimentalを使って無言で意思疎通をとる

チームでコードを書いている途中、こっちの方がいいんじゃないか?という新しい関数を作って乗り換えてみたり、もっといい変数名を思いついたのでリネームしたら予想以上に影響範囲が広かったり、新しいロジックを思いついてみたがまだ本格導入するほど自信がないといった経験はありませんか?
個人プロジェクトでは自分の好きなタイミングでリファクタや導入タイミングを決められますが、チームで開発しているときはこれらは注意事項としてチームメンバーに周知する必要があります。

  • より便利な関数ができたのでそちらを使ってほしい
  • よりわかりやすい名前にリネームしてほしい
  • セキュリティやメンテナンス性の観点からこれ以上使って欲しくない
  • まだ実装が固まってないので利用を限定するか、破壊的変更があることを分かった上で使ってほしい

Slackや口頭でも説明ができますが、時間が経つと忘れてしまうものです。できればそういった関数や変数を使おうとしている時にお知らせしてくれると嬉しいですよね。
IDEの力を借りてそれらを伝えることができるのが@Deprecated@Experimantalというアノテーションです。

環境

  • Kotlin 1.3.61
  • Android Studio 3.5.2(base IntelliJ IDEA 2019.1)

Deprecated

Deprecatedアノテーションは開発者に「これを使うのはオススメしない」と通知することができます。

val path: String
    get() = a + b + c

上の例ではもともとpathプロパティを使っていましたが、これを「これからは使って欲しくない」としたいとします。
使って欲しくない理由としてpathでは絶対パスが取得できるのか相対パスが取得できるのかが名前から推測できないという理由です。pathは元々相対パスが取得できる仕様だったとして、よりわかりやすくrelativePathを作り今後はそちらを使って欲しいとあなたは考えました。

そこでpathにDeprecatedアノテーションをつけてみます。
KotlinではDeprecatedアノテーションに2つの引数をとります。
1つめは理由です。どうしてこれを使って欲しくないのかを書きます。
2つめは移行先です。ReplaceWithを使って乗り換え先を示します。ReplaceWithは省略できませんが内容は省略が可能です。

@Deprecated("Misleading name. Replace `relativePath`", ReplaceWith("relativePath"))
val path: String
    get() = relativePath

val relativePath: String 
    get() = a + b + c

このように書くとIDEでpathを呼び出そうとした時に取り消し線が引かれて表示されます。
スクリーンショット 2019-12-04 23.03.57.png
またカーソルを合わせると先ほど入力した使ってほしくない理由が表示されます。
スクリーンショット 2019-12-04 23.04.19.png

これを見れば使おうと思った時に表示されるので忘れずに済みそうです。

またReplaceWithを書いていればIDEが自動で置換もおこなってくれます。
スクリーンショット 2019-12-04 23.12.55.png
ReplaceWithは正規表現も使えますのでうまくいけばどんな名前でもリネームが1発でできるようになります。が、結構難しいのでまずは空文字でも良いと思います。使われる頻度をゆっくり減らしていく作戦がいいでしょう。

Experimental

こちらはKotlin1.3から使えるようになったアノテーションです。頻繁に破壊的変更が発生する可能性が高いものにつけておくことで、利用者はそれを知った上で使うといった運用ができます。

Experimentalアノテーションを使うには、まずどういう試験的なものなのかを示すためにオリジナルのアノテーションを作成し、そのアノテーションにExperimentalという属性を付与します。

@Experimental
annotation class WeatherExperimental

次に実際に試験的に作っている変数や関数に先ほど作ったアノテーションを付与します。

@WeatherExperimental
fun getWeather(city: String): Weather {
}

このように書くとIDEでgetWeather関数を呼び出した時にエラーが表示されます。
スクリーンショット 2019-12-04 23.28.15.png
Experimentalアノテーションを使っている場合は呼び出し元もそれを使っていると承知の上ということを示すため呼び出す関数に@UseExperimentalアノテーションをつけます。

@UseExperimental(WeatherExperimental::class)
fun weather() {
    val api = Api()
    val weather = api.getWeather("Tokyo")
}

これらのアノテーションはライブラリによく使われますが、プロダクションコード内でも使ってみることで言葉を交わさずとも意思疎通がとれるかもしれません。

参考
https://aakira.app/blog/2018/10/whatsnew-kotlin13/

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした