はじめに
Entityや決まりきった定形コードを書くために、コードを自動生成しているという方は多いと思います。
しかし、自動生成は便利な半面、生成されたコードに変更を加えたい場合に悩みの種になります。
Model層にロジックを置くのも一つの手ではありますが、Entityの持つデータの表現方法を変えたいなど、自動生成されたクラスの中に入ってれば便利なのになぁと思う機会は多いのでは無いでしょうか?
そんなとき、KotlinのExtensionの機能が役に立ちます。
Extension
Javaでは1ファイル1クラスの原則がありますが、KotlinではExtensionとして定義することで、別ファイルにクラス・メソッドを定義することができます。どのように実現されてるかはこちらとか見てもらえればわかると思います。
実際に見てみましょう
Entityの定義(自動生成できそうなところ)
RowSampleEntity.kt
// ModelsSampleEntityのRow要素
data public class RowSampleEntity(
val id: Int,
val key: String,
val value: Int
)
ModelSampleEntity.kt
data public class ModelSampleEntity(
val subject: String,
val rows: List<RowSampleEntity>
)
Extensionの定義
ModelSampleEntityExtension.kt
// Row要素のvalueのSUM
fun ModelSampleEntity.totalValue(): Int {
return this.rows.sumBy { it.value }
}
// Rowのkeyプロパティからnext要素を取得する
fun List<RowSampleEntity>.nextByKey(key: String): RowSampleEntity? {
val currentIdx = this.indexOfFirst({ it.key == key })
return if (currentIdx < 0) null else currentIdx.let {
return this[(it + 1) % this.size]
}
}
呼び出してみる
MainActivityFragment.kt
class MainActivityFragment : Fragment() {
override fun onActivityCreated(savedInstanceState: Bundle?) {
super.onActivityCreated(savedInstanceState)
// データ作る
val entity = ModelSampleEntity(
"This is Sample Entity",
listOf(1, 2, 3, 4).map {
RowSampleEntity(id = it, key = "key_${it.toString()}", value = it * 10)
}
)
Log.d("DemoApp", "total:${entity.totalValue().toString()} nextBy: key_2 -> ${entity.rows.nextByKey("key_2")?.key ?: "fail"}")
}
}
結果
12-16 21:56:44.723 1398-1398/com.example.yashims85.demoapp D/DemoApp: total:100 nextBy: key_2 -> key_3
まとめ
それなりの制約はあるものの、メソッド外出しができると自動生成ソースの再生成とか気にしないで良いのでステキ感がありますね。