34
3分で作る Kotlin FriendlyなAPI @kikuchy

3分で作る Kotlin Friendly な API

Embed Size (px)

Citation preview

Page 1: 3分で作る Kotlin Friendly な API

3分で作る Kotlin FriendlyなAPI

@kikuchy

Page 2: 3分で作る Kotlin Friendly な API

だれ?

• Hiroshi Kikuchi (@kikuchy)

• Diverse, inc. (mixi, inc.)

• Androidアプリ作ってます

Page 3: 3分で作る Kotlin Friendly な API
Page 4: 3分で作る Kotlin Friendly な API

34301 Lines 432 Files

79.4 Lines/File

6970 Lines 125 Files

55.8 Lines/File

Page 5: 3分で作る Kotlin Friendly な API

Kotlinは 短く書けて 読みやすい

Page 6: 3分で作る Kotlin Friendly な API

本題

Page 7: 3分で作る Kotlin Friendly な API

対象

• Kotlinは使い始めくらいの人

• Androidアプリ作れるくらいにはJavaが使える人

• Javaでライブラリ作ってる(作りたい)人

Page 8: 3分で作る Kotlin Friendly な API

Javaのライブラリ作ってて困ったこと

Page 9: 3分で作る Kotlin Friendly な API

例:Keninhttps://github.com/kikuchy/kenin

Page 10: 3分で作る Kotlin Friendly な API

// 入力必須で、英字のみもしくは数字のみ可 KeninAndroid.create( mUserId, CompositeCondition.and( Conditions.requireField("require!!!! must put some value!!"), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) );

Page 11: 3分で作る Kotlin Friendly な API

きもい

Page 12: 3分で作る Kotlin Friendly な API

// 入力必須で、英字のみもしくは数字のみ可 KeninAndroid.create( mUserId, CompositeCondition.and( Conditions.requireField("require!!!! must put some value!!"), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) );

作用されるインスタンスが引数から入る

強制逆ポーランド記法

クラス名長い。かと言ってstatic importしまくるのも避けたい…

Page 13: 3分で作る Kotlin Friendly な API

目的

• 「作用されるもの」をレシーバにしたい!

• Builderパターン(や、それに類するもの)をもっと直感的に、読みやすくしたい!

Page 14: 3分で作る Kotlin Friendly な API

材料• 拡張関数

• 引数末尾がラムダ式であればメッセージ式の丸括弧を省略できること

• ラムダ式のreturnは省略できること

• thisは省略できること

• レシーバ指定関数

• 中置換数

• (演算子オーバーロード)

Page 15: 3分で作る Kotlin Friendly な API

完成予想図

// 入力必須で、英字のみもしくは数字のみ可 userId.kenin { requireField() and (alphabet() or numeric()) }

Page 16: 3分で作る Kotlin Friendly な API

読める、読めるぞ!

Page 17: 3分で作る Kotlin Friendly な API

拡張関数• TextInputLayoutに新しいメソッド(に見えるstatic

メソッド)を生やします

// トップレベルで宣言すればいい // thisでレシーバー(この場合はTextInputLayout型のインスタンス)を参照可能 fun TextInputLayout.kenin(…) = KeninAndroid.create(this, …)

Page 18: 3分で作る Kotlin Friendly な API

丸括弧の省略• 最後の引数がラムダ式のとき、メッセージ式の () を

省略できる

• ブロックのような表記が可能

// 今回は Condition 型が欲しいので、戻り値で受け取るようにする fun TextInputLayout.kenin(init: () -> Condition) = KeninAndroid.create(this, init())

Page 19: 3分で作る Kotlin Friendly な API

// この時点で、この表記が可能に! userId.kenin { // ラムダ式末尾のreturnは省略できる CompositeCondition.and( Conditions.requireField(), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) }

Page 20: 3分で作る Kotlin Friendly な API

thisの省略• staticメソッドのためにクラス名を書きたくない

• ブロック内のthisを差し替えてnon-staticなメソッド呼び出しにしてしまえばいい

// このクラスのインスタンスがthisになってくれればいい class Delegated { fun requireField() = Conditions.requireField() fun alphabet() = Conditions.alphabet() fun numeric() = Conditions.numeric() }

Page 21: 3分で作る Kotlin Friendly な API

レシーバ指定関数• 関数のレシーバを型宣言で指定できる

• 拡張関数とよく似たようなもの

// このクラスのインスタンスがthisになってくれればいい fun TextInputLayout.kenin(init: Delegated.() -> Condition) = KeninAndroid.create(this, Delegated().init())

Page 22: 3分で作る Kotlin Friendly な API

// 完成は近い! userId.kenin { CompositeCondition.and( requireField(…), CompositeCondition.or( alphabet(), numeric() ) ) }

Page 23: 3分で作る Kotlin Friendly な API

中置関数• 拡張関数の一種として中置関数を作ることができる

• 引数は必ず1つである必要がある(二項演算でなければならない)

• 特定の名前のメソッドを宣言することで演算子のオーバーロードもできるので、それで代用する手もある

// 同じようにして or のバージョンも作る infix fun Condition.and(another: Condition) = CompositeCondition.and(this, another)

Page 24: 3分で作る Kotlin Friendly な API

// 完成!! ✧\\ ٩۹( 'ω' )وو //✧ userId.kenin { requireField() and (alphabet() or numeric()) }

Page 25: 3分で作る Kotlin Friendly な API

DSLのバリエーション

Page 26: 3分で作る Kotlin Friendly な API

相性がいいものは?

• 設定項目が多くて

• 構造化が必要かもしれなくて

• Javaで書くとつらいもの

Page 27: 3分で作る Kotlin Friendly な API

Anko• https://github.com/Kotlin/anko

• DSLでAndroidのUIをつくるためのライブラリ

• たろうさんのスライドがあるのでそちらをご参照ください

• Ankoは甘くて美味しい~Ankoに見るKotlinの表現力~ #gunosybeer

• http://sssslide.com/speakerdeck.com/ntaro/ankohagan-kutemei-wei-sii-ankonijian-rukotlinfalsebiao-xian-li-number-gunosybeer

Page 28: 3分で作る Kotlin Friendly な API

kotlinx.html• https://github.com/Kotlin/kotlinx.html

• KotlinでDOMツリーを作ることができる

• サーバーサイドでのテンプレート作成はもちろん

• KotlinはJavaScriptにもトランスパイルできる、ということは…!

Page 29: 3分で作る Kotlin Friendly な API

Kotlin NoSQL

• https://github.com/cheptsov/kotlin-nosql

• MongoDBのクエリもDSLで構築可能

• (Mongoは使ったこと無いので詳しいことはわかりません)

Page 30: 3分で作る Kotlin Friendly な API

ここが惜しいよKotlin

Page 31: 3分で作る Kotlin Friendly な API

&& と || のオーバーロードはできない?

• 四則演算子やほとんどの比較演算子はオーバーロードできるのだけれど…

• Kotlinのリファレンスを見ても、&&と||は記載がない

• https://kotlinlang.org/docs/reference/operator-overloading.html

• andとかorとか書いてもダメだった

• Booleanクラスにはandとorメソッドがある

• 諦めも肝心

Page 32: 3分で作る Kotlin Friendly な API

まとめ

• Kotlinの言語機能を駆使すれば可読性が高いDSLも作れる

• JavaライブラリのKotlinラッパーを用意するとKotlinist達にも親切

Page 33: 3分で作る Kotlin Friendly な API

こちらもよろしく

Keninreal-time validation framework for Java & Kotlin

https://github.com/kikuchy/kenin

Page 34: 3分で作る Kotlin Friendly な API

@kikuchy