View
1.820
Download
0
Category
Preview:
Citation preview
3分で作る Kotlin FriendlyなAPI
@kikuchy
だれ?
• Hiroshi Kikuchi (@kikuchy)
• Diverse, inc. (mixi, inc.)
• Androidアプリ作ってます
34301 Lines 432 Files
79.4 Lines/File
6970 Lines 125 Files
55.8 Lines/File
Kotlinは 短く書けて 読みやすい
本題
対象
• Kotlinは使い始めくらいの人
• Androidアプリ作れるくらいにはJavaが使える人
• Javaでライブラリ作ってる(作りたい)人
Javaのライブラリ作ってて困ったこと
例:Keninhttps://github.com/kikuchy/kenin
// 入力必須で、英字のみもしくは数字のみ可 KeninAndroid.create( mUserId, CompositeCondition.and( Conditions.requireField("require!!!! must put some value!!"), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) );
きもい
// 入力必須で、英字のみもしくは数字のみ可 KeninAndroid.create( mUserId, CompositeCondition.and( Conditions.requireField("require!!!! must put some value!!"), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) );
作用されるインスタンスが引数から入る
強制逆ポーランド記法
クラス名長い。かと言ってstatic importしまくるのも避けたい…
目的
• 「作用されるもの」をレシーバにしたい!
• Builderパターン(や、それに類するもの)をもっと直感的に、読みやすくしたい!
材料• 拡張関数
• 引数末尾がラムダ式であればメッセージ式の丸括弧を省略できること
• ラムダ式のreturnは省略できること
• thisは省略できること
• レシーバ指定関数
• 中置換数
• (演算子オーバーロード)
完成予想図
// 入力必須で、英字のみもしくは数字のみ可 userId.kenin { requireField() and (alphabet() or numeric()) }
読める、読めるぞ!
拡張関数• TextInputLayoutに新しいメソッド(に見えるstatic
メソッド)を生やします
// トップレベルで宣言すればいい // thisでレシーバー(この場合はTextInputLayout型のインスタンス)を参照可能 fun TextInputLayout.kenin(…) = KeninAndroid.create(this, …)
丸括弧の省略• 最後の引数がラムダ式のとき、メッセージ式の () を
省略できる
• ブロックのような表記が可能
// 今回は Condition 型が欲しいので、戻り値で受け取るようにする fun TextInputLayout.kenin(init: () -> Condition) = KeninAndroid.create(this, init())
// この時点で、この表記が可能に! userId.kenin { // ラムダ式末尾のreturnは省略できる CompositeCondition.and( Conditions.requireField(), CompositeCondition.or( Conditions.alphabet(), Conditions.numeric() ) ) }
thisの省略• staticメソッドのためにクラス名を書きたくない
• ブロック内のthisを差し替えてnon-staticなメソッド呼び出しにしてしまえばいい
// このクラスのインスタンスがthisになってくれればいい class Delegated { fun requireField() = Conditions.requireField() fun alphabet() = Conditions.alphabet() fun numeric() = Conditions.numeric() }
レシーバ指定関数• 関数のレシーバを型宣言で指定できる
• 拡張関数とよく似たようなもの
// このクラスのインスタンスがthisになってくれればいい fun TextInputLayout.kenin(init: Delegated.() -> Condition) = KeninAndroid.create(this, Delegated().init())
// 完成は近い! userId.kenin { CompositeCondition.and( requireField(…), CompositeCondition.or( alphabet(), numeric() ) ) }
中置関数• 拡張関数の一種として中置関数を作ることができる
• 引数は必ず1つである必要がある(二項演算でなければならない)
• 特定の名前のメソッドを宣言することで演算子のオーバーロードもできるので、それで代用する手もある
// 同じようにして or のバージョンも作る infix fun Condition.and(another: Condition) = CompositeCondition.and(this, another)
// 完成!! ✧\\ ٩۹( 'ω' )وو //✧ userId.kenin { requireField() and (alphabet() or numeric()) }
DSLのバリエーション
相性がいいものは?
• 設定項目が多くて
• 構造化が必要かもしれなくて
• Javaで書くとつらいもの
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
kotlinx.html• https://github.com/Kotlin/kotlinx.html
• KotlinでDOMツリーを作ることができる
• サーバーサイドでのテンプレート作成はもちろん
• KotlinはJavaScriptにもトランスパイルできる、ということは…!
Kotlin NoSQL
• https://github.com/cheptsov/kotlin-nosql
• MongoDBのクエリもDSLで構築可能
• (Mongoは使ったこと無いので詳しいことはわかりません)
ここが惜しいよKotlin
&& と || のオーバーロードはできない?
• 四則演算子やほとんどの比較演算子はオーバーロードできるのだけれど…
• Kotlinのリファレンスを見ても、&&と||は記載がない
• https://kotlinlang.org/docs/reference/operator-overloading.html
• andとかorとか書いてもダメだった
• Booleanクラスにはandとorメソッドがある
• 諦めも肝心
まとめ
• Kotlinの言語機能を駆使すれば可読性が高いDSLも作れる
• JavaライブラリのKotlinラッパーを用意するとKotlinist達にも親切
こちらもよろしく
Keninreal-time validation framework for Java & Kotlin
https://github.com/kikuchy/kenin
@kikuchy
Recommended