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

Kotlin向けModelMapper的なライブラリ、KMapperを作った

2020/3/6追記

当初はこのライブラリの名前をMapKとしていましたが、MapKはオーガナイゼーションの名前として、ライブラリ名はKMapperに変更しました。

前書き

Kotlin向けModelMapper的なライブラリが欲しかったので作りました。
この記事では、KMapperの基本的な使い方についてまとめます。
バージョンは0.1時点での内容です。

ライブラリのソースコードはGitHubに公開してあります。

導入方法

JitPackにて公開しており、MavenGradleといったビルドツールから利用できます。
詳しい導入方法は以下のリンクからご確認ください。

開発背景

Javaでは、POJOに対してオブジェクトからデータをマップできるModelMapperという便利なライブラリが有ります。

一方、このライブラリは当然ですがKotlinには対応していません。
Kotlinは基本的にコンストラクタで初期化を完了する一方、ModelMapperは「引数無しコンストラクタでインスタンス生成 -> セッターでデータをそれぞれマッピング」という手順での初期化を想定しているためです。

無理やりModelMapperを使ってKotlinのオブジェクトを初期化することも不可能ではありませんが、その場合immutabilityNull安全が犠牲になったりと、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クラスのインスタンスからは、valvarで定義されたプロパティ(KProperty)のみを抽出してマッピングを行います。

Javaへの対応に関して

前述の通り、valvarで定義されたプロパティのみが対象であるため、Javaのゲッターからは抽出を行っておりません。
技術的には不可能ではありませんが、現状では敢えて対応するほどでもないと考えています。

終わりに

今回は自作のKotlin向けModelMapper的なライブラリ、KMapperに関して書きました。

引数間の変換機能なども有りますが、長くなるので個別の記事としてまとめようと思います。
ドキュメント・テスト等足りない部分は多々ありますが、こちらも今後対応していく予定です。

PR、質問等も募集中です。
是非使ってみて下さいm(_ _)m

wrongwrong
リフレクションを用いたKotlin JVM向けのマッピングライブラリを作ってる人です。 https://github.com/ProjectMapK
https://wrongwrong163377.hatenablog.com/
microad
データとテクノロジーをかけ合わせたマーケティングプラットフォームを提供する会社です。
https://www.microad.co.jp/
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