ticktakclockの日記

技術ポエムを綴ったりします。GitHub idも同じです (@ticktakclock)

kotlinで別パッケージの同じクラス名の衝突を回避する

こんにちは、tkyです。

Kotlinの小ネタです。

タイトルのとおりなのですが、こういったことってほとんどないとは思うのでいざというときどうするか迷う系のやつです。

ドメインとしてのクラス名と被ってしまう

例えば イベント情報 を取り扱うドメインがあったとして Event クラスを作ったとします。

package com.hatenablog.ticktakclock.model.Event

data class Event(val id: Int /* その他引数 */) {}

次にFirebaseに送るトラッキングイベントを Event クラスとしてモデル化します

package com.hatenablog.ticktakclock.track.Event

sealed class Event(val name: String) {
    class Favorite(): Event("user_favorite") // お気に入りしたことをトラッキング
}

この2つのクラスを一緒に使おうとしたときにクラス名の衝突が起こってしまい、どちらかはフルパッケージ名で記述する必要が出てきます。

クラス名が衝突した!その前に

まず名前が衝突しないようにクラス名の変更リファクタリングを視野に入れましょう。

この場合、ドメインとしてのEventは共通仕様なので変えることがかなり難しいですが、トラッキングイベントの方は他の領域関係なく考え直すことができます。

package com.hatenablog.ticktakclock.track.TrackingEvent のように変えることで衝突が発生しない平和な世界を作れるはずです。

※個人的にはパッケージ名にtrackが入っているので更にTrackingEventという命名をつけることに多少違和感を覚えますが、名前回避のため・・・・

import にas を使う

外部のライブラリのクラス名と衝突してしまってどうしても平和的な解決ができない場合、 こちらのドキュメントに書いてあるとおり、 as キーワードを使うことでそのファイル内で別の名前を使用することができるようになります。

package com.hatenablog.ticktakclock.model.Event

package com.hatenablog.ticktakclock.track.Event as TrackingEvent // このファイル内でのみTrackingEventとして扱える

dogwood008.github.io

まとめ

あまりこういったことに出会わないため忘れがちですがいざというときに使えるテクニックかなと思います。

とはいえ前提として名前が被らないようにクラス設計するテクニック自体も身につけていきたいところですね。

  • asキーワードで局所的に別名を指定することができる
  • asキーワード使う前にもとのクラス名をリファクタできるか考えること
  • まだまだKotlinの知らない(あまり使っていない)言語機能ありそう