Link
Embed
Share
Beginning
This slide
Copy link URL
Copy link URL
Copy iframe embed code
Copy iframe embed code
Copy javascript embed code
Copy javascript embed code
Share
Tweet
Share
Tweet
Slide 1
Slide 1 text
Double Context Extension Retty Tech Cafe #8 2016-12-09 長澤 太郎
Slide 2
Slide 2 text
自己紹介 ● 長澤 太郎 たろーって呼んでね ○ @ngsw_taro ● エンジニア@エムスリー株式会社 ○ Android, Kotlin, Java, Spring, Railsなど ● Kotlinエバンジェリスト ● ディズニーが好き
Slide 3
Slide 3 text
Kotlinいいよね! ● 型推論 ● ラムダ式 ● NULL安全 ● Extension ● 委譲プロパティ ● 分解宣言 ● コルーチン ● 型エイリアス
Slide 4
Slide 4 text
Kotlinいいよね! ● 型推論 ● ラムダ式 ● NULL安全 ● Extension ● 委譲プロパティ ● 分解宣言 ● コルーチン ● 型エイリアス
Slide 5
Slide 5 text
Extension(拡張) ● 拡張関数 ● 拡張プロパティ fun String.hello() { println("Hello, $this") } "world".hello() val String.initial: Char? get()=firstOrNull()?.toUpperCase() "world".initial
Slide 6
Slide 6 text
拡張関数じゃ物足りない問題
Slide 7
Slide 7 text
こんな関数呼び出しをしたい! class MyActivity: FragmentActivity { ... fun showMessage() { // myDialog.show(supportFragmentManager, "tag") myDialog.show("tag") } }
Slide 8
Slide 8 text
こんな関数呼び出しをしたい! class MyActivity: FragmentActivity { ... fun showMessage() { // myDialog.show(supportFragmentManager, "tag") myDialog.show("tag") } } DialogFragmentに拡張関数showを生やせば? いや、プロパティsupportFragmentManagerが必要だ... →FragmentManagerに依存
Slide 9
Slide 9 text
クラスの中に拡張関数を定義してみる class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } fun showMessage() { myDialog.show("tag") } }
Slide 10
Slide 10 text
クラスの中に拡張関数を定義してみる class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } fun showMessage() { myDialog.show("tag") } } イケる!?
Slide 11
Slide 11 text
再利用ができない問題... class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } } class YourActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } }
Slide 12
Slide 12 text
再利用ができない問題... class MyActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } } class YourActivity: FragmentActivity { ... fun FragmentDialog.show(tag: String?) { show(supportFragmentManager, tag) } } 同じコードが重複する
Slide 13
Slide 13 text
どうするか?
Slide 14
Slide 14 text
if (ちょっとした実験とか趣味のコード) { } else { }
Slide 15
Slide 15 text
if (ちょっとした実験とか趣味のコード) { recommend(DoubleContextExtension) } else { }
Slide 16
Slide 16 text
if (ちょっとした実験とか趣味のコード) { recommend(DoubleContextExtension) } else { recommend(Extension至上主義を捨てよ) }
Slide 17
Slide 17 text
Double Context Extension ● 2つのコンテキストを持った拡張関数 ● 命名 by 私 ● 見た目: 型Aの定義中で、型Aに依存しながらも型Bの拡張関 数を生やすことができる class MyActivity: FragmentActivity { ... fun showMessage() { myDialog.show("tag") } }
Slide 18
Slide 18 text
Double Context Extension ● 実際のコード: 「B型の拡張関数」を返す「A型の拡張プロパ ティ」を定義する // どこか適当なファイル val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) }
Slide 19
Slide 19 text
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) } class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... }
Slide 20
Slide 20 text
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) } class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... } FragmentActivityの 拡張関数showの呼び出し
Slide 21
Slide 21 text
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) } class MyActivity: FragmentActivity { fun showMessage() { myDialog.(this.show)("tag") } ... } こう書いても同じ
Slide 22
Slide 22 text
どう解釈されるか val FragmentActivity.show: DialogFramgnet.(String?)->Unit get() { tag -> show(supportFragmentManager, tag) } class MyActivity: FragmentActivity { fun showMessage() { myDialog.show("tag") } ... } 返って来た拡張関数オブジェクトを myDialogをレシーバに、 ”tag”を引数にして呼び出す
Slide 23
Slide 23 text
まとめ ● 拡張関数って便利だよね ● でも限界がある ● Double Context Extensionという提案
Slide 24
Slide 24 text
まとめ ● 拡張関数って便利だよね ● でも限界がある ● Double Context Extensionという提案 ● 変なことしないで素直なコードを心がけましょう