2020/3/6追記
当初はこのライブラリの名前をMapK
としていましたが、MapK
はオーガナイゼーションの名前として、ライブラリ名はKMapper
に変更しました。
前書き
Kotlin
向けModelMapper
的なライブラリが欲しかったので作りました。
この記事では、KMapper
の基本的な使い方についてまとめます。
バージョンは0.1
時点での内容です。
ライブラリのソースコードはGitHub
に公開してあります。
導入方法
JitPack
にて公開しており、Maven
やGradle
といったビルドツールから利用できます。
詳しい導入方法は以下のリンクからご確認ください。
開発背景
Java
では、POJO
に対してオブジェクトからデータをマップできるModelMapper
という便利なライブラリが有ります。
一方、このライブラリは当然ですがKotlin
には対応していません。
Kotlin
は基本的にコンストラクタで初期化を完了する一方、ModelMapper
は「引数無しコンストラクタでインスタンス生成 -> セッターでデータをそれぞれマッピング」という手順での初期化を想定しているためです。
無理やりModelMapper
を使ってKotlin
のオブジェクトを初期化することも不可能ではありませんが、その場合immutability
やNull
安全が犠牲になったりと、Kotlin
の良さが殺されてしまいます。
また、デフォルト引数に関しても利用することができません。
つまり、そういった機能を十全に使おうと思えばマッパーの利用をあきらめ手動で引数を調整して書くしか有りませんでした。
このため、src
からKotlin
のコンストラクタやファクトリーメソッドを呼び出せるようなマッパーライブラリが欲しいと思いました。
なにができるか
以下のように、KMapper
を用いることで、Dst
クラスのコンストラクタをsrc
のプロパティから呼び出すことができます。
// KMapperを使わない場合
val dst = Dst(
param1 = src.param1,
param2 = src.param2,
param3 = src.param3,
param4 = src.param4,
param5 = src.param5,
...
)
// KMapperを使う場合
val newInstance = KMapper(::Dst).map(src)
KMapperの引数
KMapper
の引数は、基本的にはコンストラクタやファクトリメソッド、インスタンス関数を含むメソッドリファレンス(≒ KFunction<*>
)です。
クラスを引数とすることで、プライマリコンストラクタ、もしくはKConstructor
アノテーションを振ったコンストラクタ/ファクトリーメソッドを呼び出し対象とすることも可能です。
Javaへの対応に関して
基本的にJava
のクラス・関数には対応しません。
マッピングにはKotlin
のメタデータを利用していることと、Java
では引数の名前が取得できない場合があることが理由です。
srcに指定できる内容
マップ元には以下が指定できます。
Map<String, Any?>
-
Kotlin
クラスのインスタンス -
Kotlin
クラスのインスタンス、Map<String, Any?>
、Pair<String, Any?>
から構成される可変長引数
Kotlin
クラスのインスタンスからは、val
やvar
で定義されたプロパティ(KProperty
)のみを抽出してマッピングを行います。
Javaへの対応に関して
前述の通り、val
やvar
で定義されたプロパティのみが対象であるため、Java
のゲッターからは抽出を行っておりません。
技術的には不可能ではありませんが、現状では敢えて対応するほどでもないと考えています。
終わりに
今回は自作のKotlin
向けModelMapper
的なライブラリ、KMapper
に関して書きました。
引数間の変換機能なども有りますが、長くなるので個別の記事としてまとめようと思います。
ドキュメント・テスト等足りない部分は多々ありますが、こちらも今後対応していく予定です。
PR、質問等も募集中です。
是非使ってみて下さいm(_ _)m