Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Androidで使えるKotlinレシピ

Bcd7ba3b99b88a1d906961169b467b0a?s=47 kamedon
July 03, 2017

 Androidで使えるKotlinレシピ

クラスメソッドが運営するIT系技術ブログDevelopers.IOのカンファレンスイベントDevelopers.IO 2017にて、セッション「Androidで使えるKotlinレシピ」を発表しました。

#cmdevio2017

Bcd7ba3b99b88a1d906961169b467b0a?s=128

kamedon

July 03, 2017
Tweet

Transcript

  1. "OESPJEͰ࢖͑Δ,PUMJOϨγϐ ,BNFEPO

  2. ϓϩϑΟʔϧ  • Χϝυϯ • Kotlin޷͖Ͱ͢ • AndroidͷΞϓϦ։ൃ΍ͬͯ·͢ • ϘʔυήʔϜ͕޷͖Ͱ͢

    Akiba.BoardGameओ࠵
  3. ,PUMJO͕"OESPJEެࣜݴޠԽ㊗ 

  4.  Έͳ͞Μ
 KotlinͰշదAndroidΞϓϦ։ൃͯ͠·͔͢ʁ

  5. ,PUMJO  w+FUCSBJOT੡ϦϦʔε w+7.ݴޠɺ,PUMJO/BUJWF w#FUUFS+BWB+BWBޓ׵ੑ w੩తܕ෇͚ wΦϒδΣΫτࢦ޲ w/VMM҆શ ΑΓ/VMMѻ͍΍͘͢ͳΔʣ

  6. ର৅ऀ  w,PUMJOΛҰ౓͸৮ͬͨ͜ͱ͕͋Δਓ w,PUMJOͷػೳ͸ͳΜͱͳ͘Θ͔Δ͕ɺ
 "OESPJEͰͲ͏׆͔͢೰ΜͰ͍Δਓ w,PUMJOΛ࣮ફతͳίʔυΛ஌Γ͍ͨํ KotlinͷྗΛ։์͍ͤͨ͞

  7. "OESPJEͰ,PUMJOͷྗΛղ͖์ͭϨγϐ  ,PUMJOͷྗΛղ͖์ͭΛΩʔϫʔυΛ٧ΊࠐΈ·ͨ͠
 ݴޠ࢓༷ͷࡉ͍ͱ͜Ζ·Ͱࠓճ͸ѻ͍·ͤΜ w1SPQFSUJFTBOE'JFMET w%4- w%*

  8. "OESPJEͰ,PUMJOͷྗΛղ͖์ͭϨγϐ  Properties and Fields

  9. ,PUMJOͷ1SPQFSUJFTBOE'JFMET  wLFZXPSEQSPQFSUZ/BNF<1SPQFSUZ5ZQF>< QSPQFSUZ@JOJUJBMJ[FS>
 <HFUUFS><TFUUFS> wLFZXPSEWBM SFBEPOMZ WBS NVUBCMF 

    w1SPQFSUZ5ZQF<ʜ>
 ͳ͠ /PU/VMM ɺ /VMMBCMF ɺ 1MBUGPSN5ZQF  wWBMIPHF4USJOHl5FTUz wWBSGPP4USJOH OVMM
  10. 1SPQFSUJFTBOE'JFMETͷબͼํʹ͍ͭͯ  WBSΑΓWBMɺ ΑΓ /PU/VMM ɺΑΓ ͷ΄͏͕ΑΓ҆શ wWBMͰࣄ଍ΓΔͷͰ͋Ε͹ɺWBMΛ࢖༻͠Α͏͢Δ
 ্ॻ͖͠ͳ͍Α͏ʹؾΛ͚ͭΔͰ͸ͳ͘ɺ
 ্ॻ͖Ͱ͖ͳ͍Α͏ʹ͢Δ

    wΫϥε੹຿తʹ͸WBM͕ͩɺ"OESPJEͷ࢓্༷WBS΍ ʹͤ͟ Δ௥͑ͳ͍͕࣌ଟʑ͋Δ w͋Δఔ౓ճආ͢ΔςΫχοΫ͕ଘࡏ͢Δ
  11. 1SPQFSUJFTBOE'JFMETͷࢦ਑Λ࡞ͬͯΈͨ 

  12. ܕͷબͼํ 

  13. ॳظԽ࣌ʹΠϯελϯεԽͰ͖Δ  ActivityͷϥΠϑαΠΫϧͳͲʹґଘ͠ͳ͍৔߹ class SampleActivity : AppCompatActivity() {
 
 val

    adapter = ItemAdapter()
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_sample)
 val listView = (findViewById(R.id.listView) as ListView)
 listView.adapter = adapter
 }
 }
  14. ܕͷબͼํ 

  15. "DUJWJUZ࢓༷ͷ͍ͤͰॳظԽͰ͖ͳ͍  ίϯύΠϧ͸௨Δ͕ɺNPEʹͳΔ setContentViewҎ߱Ͱͳ͍ͱfindViewById͸औಘͰ͖ͳ͍ class SampleActivity : AppCompatActivity() {
 


    val adapter = ItemAdapter()
 
 val listView = (findViewById(R.id.listView) as ListView)
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_sample)
 listView.adapter = adapter
 }
 }
  16. "DUJWJUZϥΠϑαΠΫϧͷ͍ͤͰॳظԽͰ͖ͳ͍  listViewΛࢀর͞ΕΔ·ͰॲཧΛ஗Ԇ͢Δ setContentViewҎ߱Ͱࢀর͞Ε͍ͯΔͨΊ໰୊ͳ͠ class SampleActivity : AppCompatActivity() {
 


    val adapter = ItemAdapter()
 
 val listView by lazy {
 (findViewById(R.id.listView) as ListView)
 }
 
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_sample)
 listView.adapter = adapter
 }
 }
  17. ܕͷબͼํ 

  18. ֎෦͔Βґଘؔ܎Λղܾ͢Δඞཁ͋Γ  class SampleActivity : AppCompatActivity() {
 val binding by

    lazy {
 DataBindingUtil.setContentView<ActivitySampleBinding>(this, R.layout.activity_sample)
 }
 }
 class SampleFragment : Fragment() {
 lateinit var binding: FragmentSampleBinding 
 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
 binding = DataBindingUtil.inflate<FragmentSampleBinding> (inflater, R.layout.fragment_sample, container, false)
 
 }
 }
  19. ֎෦͔Βґଘؔ܎Λղܾ͢Δඞཁ͋Γ  class SampleFragment : Fragment() {
 lateinit var binding:

    FragmentSampleBinding
 override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
 binding = DataBindingUtil.inflate<FragmentSampleBinding> (inflater, R.layout.fragment_sample, container, false)
 
 }
 } inflaterͱcontainer͸onCreateViewͰ ࢀরͰ͖ΔΑ͏ʹͳΔͨΊɺby lazyͰॻ͘͜ͱ͕Ͱ͖ͳ͍
  20. ܕͷબͼํ 

  21. ϓϥοτϑΥʔϜܕͱઓ͏  +BWBͷϝιου͸ɺ ϓϥοτϑΥʔϜܕ ʹͳΔ wϓϥοτϑΥʔϜܕ͸ɺ/PU/VMMͰ΋/VMMBCMFͰ΋͋Δ w΋ͪΖΜ/PU/VMMͷͱ͖ʹ/VMM৔߹͸/1&ʹͳΔ

  22. ϓϥοτϑΥʔϜܕͱઓ͏  val listView: View = findViewById(R.id.listView)
 val listView: View?

    = findViewById(R.id.listView)  ϓϥοτϑΥʔϜܕ ͷ৔߹͸໌ࣔతʹܕΛॻ͘ wϓϥοτϑΥʔϜܕ͸ɺܕਪ࿦͠ͳ͍΄͏͕٢ w/PU/VMMͩͱࢥ͏ͷͰ͋Ε͹ɺ/PU/VMMʹ͢Δ w/VMMͷॠؒʹ/1&ͰམͪΔͷͰૣظʹόάΛൃݟͰ͖Δ w,PUMJO͸/1&Ͱམͱ͞ͳ͍ٕज़Ͱ͸ͳ͘ɺ/VMMΛద੾ʹѻ͍΍͘͢ ͯ͘͠ΕΔɻҙਤ͠ͳ͍ͷͰ͋Ε͹མͱ͢΂͖ɻ
  23. "OESPJEͰ,PUMJOͷྗΛղ͖์ͭϨγϐ  DSL (Domain Specific Language)

  24. %4-  w͋ΔಛఆͷྖҬʢυϝΠϯʣͷ໰୊Λղܾ͢ΔͨΊʹ࡞ΒΕɺ ͦΕҎ֎ͷྖҬͷ໰୊Λղ͘͜ͱ͸૝ఆ͍ͯ͠ͳ͍ɻ wࠓճ͸7BMJEBUJPOΛྫʹ͢Δ wྫ͑͹ςΩετϘοΫεͳͲͰ6TFSͷOBNF͕ೖྗ͞Εͨͱ͖ ʹɺ༗ޮͳ΋ͷ͔ߟ͑Δ wจࣈ਺͸ɺdจࣈ·Ͱ༗ޮ

  25. ࠷ॳ͸ྑ͔͕ͬͨʜ  ػೳ௥Ճ͸͞Ε͍ͯ͘… • ৽ͨʹageΛ௥Ճ: 20ࡀҎ্ • name͕NGϫʔυΛؚ·ͳ͍ class User(val

    name: String) {
 
 fun vaildate(): Boolean {
 return name.length in 1..16 }
 
 }
  26. ຊ౰ͷઓ͍͸͜Ε͔Βͩͥ  • ԿͰΤϥʔʹͳ͔ͬͨɺΤϥʔϝοηʔδ͍ͩͨ͠
 ɹɹɹɹɹɹɹɹɹʘ(^o^)ʗ class User(val name: String, val

    age: Int) {
 
 fun vaildate(): Boolean {
 return name.length in 1..16 &&
 name in listOf("hoge","foo") &&
 age >= 20
 }
 
 }
  27. 7BMJEBUJPOͷ%4-Λ࡞ͬͯɺϦϑΝΫλϦϯά  • Validation֤ཁૉͷ͋Δ΂͖࢟ɺͦ͏Ͱͳ͍࣌ͷϝοηʔδ • A ͸ B Ͱ͋Δɻͦ͏Ͱͳ͍࣌ɺ Error

    Message class User(val name: String, val age: Int) {
 
 fun vaildate(): Boolean {
 return name.length in 1..16 &&
 name in listOf("hoge","foo") &&
 age >= 20
 }
 
 }
  28. %4-Ͱཁ݅  wυϝΠϯΛఆٛ͢Δදݱྗ wຊ࣭ʹूதͰ͖ΔΑ͏ʹγϯλοΫεΛΘ͔Γ΍͘͢ w*%&ͷػೳΛ͍͔͑ΔΑ͏ʹܕͳͲอ؅Ͱ͖Δ͔ wυϝΠϯͷݴ༿Ͱ͔͚Δ w"͸#Ͱ͋Δɻͦ͏Ͱͳ͍࣌ɺ&SSPS.FTTBHF

  29. ͍͖ͳΓ࠷ऴܕΛͲʔΜ  • User be {validation} not “error message” •

    Validation͕૿͑ͯ΋໰୊ͳ͠ • υϝΠϯͷจ๏ͷ··ͰɺಡΈ΍͍͢ class User(val name: String, val age: Int) {
 val validation = Validation<User> { be { age >= 20 } not "成人のみです"
 be { name.length in 1..16 } not "1-16文字以下で"
 be { name !in listOf("hoge", "foo") } 
 not "NGワード以外で"
 }
 fun vaildate() = validation.validate(this)
 }
  30. ͞ΒʹಡΈ΍͘͢  • ΍Γա͗ײ͕͋Δ class User(val name: String, val age:

    Int) {
 val validation = Validation<User> { of(age) be { it >= 20 } not "成人のみです"
 of(name) be { it.length in 1..16 } not "1-16文字以下で"
 of(name) be { it !in listOf("hoge", "foo") } 
 not "NGワード以外で"
 }
 fun vaildate() = validation.validate(this)
 }
  31. %4-Λ࣮ݱ͢Δٕज़  wWBS͔ΒWBMʹ͢ΔͨΊʹ#VJMEFS wఆٛͬΆ͘͢ΔPQFSBUPSJOWPLF w୹͘͢ΔϨγʔόʔࢦఆMBNCEB w࠷ޙͷҾ਺ͷ৔߹͸ ΛলུՄೳ w୹͘͢Δ&YUFOTJPOT'VODUJPOTPS1SPQFSUJFT wӳޠͬΆ͍จ๏ʹJOpY

  32. ఆٛͬΆ͘͢ΔPQFSBUPSJOWPLF  class Validation<in T>(val validations: List<Pair<T.() -> Boolean, String>>)

    {
 
 companion object { 
 operator fun <T> invoke(init: ValidationBuilder<T>.() -> Unit): Validation<T> { 
 val builder = ValidationBuilder<T>()
 return builder.apply(init).build()
 }
 } Validation<User> { be { age >= 20 } not “成人のみです” } operator invokeͰinvokeΛলུɺValidation()Ͱ࣮ߦͰ͖Δ ࠷ޙ͕ϥϜμͳͷͰ()লུՄೳ͠ɺ{}ʹͳΔ
  33. ఆٛͬΆ͘͢ΔPQFSBUPSJOWPLF  class Validation<in T>(val validations: List<Pair<T.() -> Boolean, String>>)

    {
 
 companion object { 
 operator fun <T> invoke(init: ValidationBuilder<T>.() -> Unit): Validation<T> { 
 val builder = ValidationBuilder<T>()
 return builder.apply(init).build()
 }
 } Validation<User>.invoke({…}) Validation<User>.invoke{…} Validation<User>{…} operator invokeͰinvokeΛলུɺValidation()Ͱ࣮ߦͰ͖Δ ࠷ޙ͕ϥϜμͳͷͰ()লུՄೳ͠ɺ{}ʹͳΔ
  34. WBS͔ΒWBMʹ͢ΔͨΊʹ  BuilderΛ࡞੒͠ɺ • ఆ͕ٛऴΘΔ·Ͱ͸mutableʹͯ͠Buildޙ͸immutableʹ͢Δ • Builder಺ʹఆٛ༻ͷγϯλοΫεΛด͡ΊΔ class Validation<in T>(val

    validations: List<Pair<T.() -> Boolean, String>>) {
 fun validate(value: T) = validations.filter { !it.first.invoke(value) }.map { it.second }
 }
 class ValidationBuilder<T> { var validations: MutableList<Pair<T.() -> Boolean, String>> = mutableListOf()
 
 fun build(): Validation<T> {
 return Validation(validations)
 }
 }
  35. ϨγʔόʔࢦఆMBNCEB  class ValidationBuilder<T> {
 var validations: MutableList<Pair<T.() -> Boolean,

    String>> = mutableListOf() 
 ɹɹfun be(validate: T.() -> Boolean) = validate } Validation<User> { be { age >= 20 } not “成人のみです” } TͷvalidateΛϥϜμͰ࡞੒͢Δɺ࠷ޙͷϥϜμ͸লུՄೳ T.() -> Boolean) = (T)->Boolean ͷҧ͍͸ʁ
  36. 5 #PPMFBO 5 #PPMFBOͷҧ͍͸ʁ  Validation<User> { be { it.age

    >= 20 } not “成人のみです” //fun be(validate: (T) -> Boolean) = validate be { this.age >= 20 } not “成人のみです” //fun be(validate: T.() -> Boolean) = validate } Ϩγʔόʔࢦఆͷ৔߹this͕TʹͳΔ
  37. ୹͘͢Δ&YUFOTJPOT'VODUJPOTPS1SPQFSUJFT  class ValidationBuilder<T> {
 var validations: MutableList<Pair<T.() -> Boolean,

    String>> = mutableListOf()
 fun be(validate: T.() -> Boolean) = validate infix fun (T.() -> Boolean).not(error: String) {
 validations.add(this to error)
 } } Validation<User> { be { age >= 20 } not “成人のみです” } validateͯ͠ແޮͳ஋ͩͬͨ৔߹Τϥʔϝοηʔδฦ͢Α͏ʹ͢Δ (T.() -> Boolean)ʹ֦ுؔ਺Λ࣮૷͠Pairʹͯ͠add͢Δ
  38. ӳޠͬΆ͍จ๏ʹJOpY  class ValidationBuilder<T> {
 var validations: MutableList<Pair<T.() -> Boolean,

    String>> = mutableListOf()
 fun be(validate: T.() -> Boolean) = validate infix fun (T.() -> Boolean).not(error: String) {
 validations.add(this to error)
 } } Validation<User> { be { age >= 20 } not “成人のみです” } infix༗Γແ͠Ͳ͏ͳΔ͔ݟͯΈ·͠ΐ͏
  39. ӳޠͬΆ͍จ๏ʹJOpY  Validation<User> { be { it.age >= 20 }.not(“成人のみです”)

    //fun (T.() -> Boolean).not(error: String) 
 be { this.age >= 20 } not “成人のみです” //infix fun (T.() -> Boolean).not(error: String) } infixΛ࢖͏͜ͱͰ.() Λͳ͘͠ɺεϖʔε۠੾Γʹ ӳޠͬΆ͘Ͱ͖Δ
  40. %4-Λ࣮ݱ͢Δٕज़  wWBS͔ΒWBMʹ͢ΔͨΊʹ#VJMEFS wఆٛͬΆ͘͢ΔPQFSBUPSJOWPLF w୹͘͢ΔϨγʔόʔࢦఆMBNCEB w࠷ޙͷҾ਺ͷ৔߹͸ ΛলུՄೳ w୹͘͢Δ&YUFOTJPOT'VODUJPOTPS1SPQFSUJFT wӳޠͬΆ͍จ๏ʹJOpY ͳΜͰ΋͍͍͔ΒɺDSLͷαϯϓϧΛ࡞ͬͯΈΑ͏

    Kotlinྗ͕ඈ༂తʹΞοϓ͠·͢ʂ
  41. "OESPJEͰ,PUMJOͷྗΛղ͖์ͭϨγϐ  DI Container (Dependency Injection Container)

  42. ೔ຊޠ8JLJQFEJBͩͱʜ  lґଘੑͷ஫ೖʢ͍ͦΜ͍ͤͷͪΎ͏ʹΎ͏ɺӳ %FQFOEFODZJOKFDUJPOʣͱ͸ɺίϯϙʔωϯτؒͷ ґଘؔ܎ΛϓϩάϥϜͷιʔείʔυ͔Βഉআ͠ɺ֎෦ ͷઃఆϑΝΠϧͳͲͰ஫ೖͰ͖ΔΑ͏ʹ͢Διϑτ΢Σ ΞύλʔϯͰ͋Δɻz 8JLJQFEJBґଘੑͷ஫ೖ

  43. ೔ຊޠ8JLJQFEJBͩͱʜ  lґଘੑͷ஫ೖʢ͍ͦΜ͍ͤͷͪΎ͏ʹΎ͏ɺӳ %FQFOEFODZJOKFDUJPOʣͱ͸ɺίϯϙʔωϯτؒͷ ґଘؔ܎ΛϓϩάϥϜͷιʔείʔυ͔Βഉআ͠ɺ֎෦ ͷઃఆϑΝΠϧͳͲͰ஫ೖͰ͖ΔΑ͏ʹ͢Διϑτ΢Σ ΞύλʔϯͰ͋Δɻz 8JLJQFEJBґଘੑͷ஫ೖ ґଘੑͷ஫ೖʁ

  44. ӳޠ൛8JLJQFEJBͩͱʜ  l*OTPGUXBSFFOHJOFFSJOH EFQFOEFODZ JOKFDUJPOJTBUFDIOJRVFXIFSFCZPOFPCKFDU TVQQMJFTUIFEFQFOEFODJFTPGBOPUIFSPCKFDU "EFQFOEFODZJTBOPCKFDUUIBUDBOCFVTFE B TFSWJDF z

    8JLJQFEJB%FQFOEFODZJOKFDUJPO
  45. ӳޠ൛8JLJQFEJBͩͱʜ  l*OTPGUXBSFFOHJOFFSJOH EFQFOEFODZ JOKFDUJPOJTBUFDIOJRVFXIFSFCZPOFPCKFDU TVQQMJFTUIFEFQFOEFODJFTPGBOPUIFSPCKFDU "EFQFOEFODZJTBOPCKFDUUIBUDBOCFVTFE B TFSWJDF z

    8JLJQFEJB%FQFOEFODZJOKFDUJPO dependency͸ΦϒδΣΫτ ΦϒδΣΫτͷ஫ೖ
  46. Πϝʔδ͠Α͏  DIͬΆ͍ͷ͸Ͳͬͪʁ ۩ࡐɺຯΛௐ੔ɺม͑΍͍͢ͷ͸

  47. Πϝʔδ͠Α͏  DIͬΆ͍ͷ͸Ͳͬͪʁ ۩ࡐɺຯΛௐ੔ɺม͑΍͍͢ͷ͸

  48. ιʔείʔυͩͱ  class FriedRice val friedRice = FriedRice() class BowlOFRice(val

    rice: Rice, val topping: Topping) interface Topping interface Rice class JapaneseRice : Rice class BeefTopping : Topping //オブジェクトを入れる val beefBowl = BowlOFRice(JapaneseRice(), BeefTopping()) ※ઃܭ࣍ୈͰνϟʔϋϯ΋DIԽͰ͖·͢
  49. %*ͷࢫຯɿมߋʹڧ͍  ஫ೖ͞ΕΔ΋ͷ͸ΦϒδΣΫτ͕ͩ
 ΠϯλʔϑΣʔεʢ࢓༷ʣʹґଘͨ͠΄͏͕ΑΓॊೈ wڇက͡Όͳͯ͘ɺ;Γ͔͚ကͰ΋໰୊ͳ͠ wܧঝͰͳ͘ɺ࢓༷ʹґଘ͍ͯ͠ΔͨΊՄೳ wςετ ຯݟ ͷͱ͖ʹϥΠεΛϞοΫʹ͢Δ͜ͱͰɺ
 ຯݟՄೳ

  50. %*  DI Container (Dependency Injection Container)

  51. %*ͱ%*$POUBJOFS  %*$POUBJOFS͸
 %*Λ࣮ݱ͢ΔͨΊͷศརπʔϧͰ͔͠ͳ͍ wઌఔͷઆ໌Ͱ%BHHFSͳͲͰ͖ͯ·͔ͨ͠ʁ class BowlOFRice(val rice: Rice, val

    topping: Topping) //オブジェクトを入れる val beefBowl = BowlOFRice(JapaneseRice(), BeefTopping())
  52. %*$POUBJOFSͷࢫຯ  ࠷େͷϞνϕʔγϣϯɿΊΜͲ͏͍͘͞ w͍͍ͪͪΦϒδΣΫτ࡞੒͢Δͷ͕໘౗ w౎౓OFX͢Δඞཁ͕ͳ͘࢖͍·Θ͍ͨ͠ w஫ೖ͢ΔΦϒδΣΫτΛมߋ͢Δ࣌ʹɺ
 ͢΂ͯม͑Δͷ໘౗ ґଘؔ܎Λهड़ͨ͠Β উखʹੜ੒ɺ஫ೖͯ͘͠ΕͨΒ͍͍ͷʹ

  53. %*$POUBJOFSͷࢫຯ  ࠷େͷϞνϕʔγϣϯɿΊΜͲ͏͍͘͞ w͍͍ͪͪΦϒδΣΫτ࡞੒͢Δͷ͕໘౗ w౎౓OFX͢Δඞཁ͕ͳ͘࢖͍·Θ͍ͨ͠ w஫ೖ͢ΔΦϒδΣΫτΛมߋ͢Δ࣌ʹɺ
 ͢΂ͯม͑Δͷ໘౗ ґଘؔ܎Λهड़ͨ͠Β উखʹੜ੒ɺ஫ೖͯ͘͠ΕͨΒ͍͍ͷʹ DI

    Container͞Μ͓ئ͍͠·͢
  54. Πϝʔδ͠Α͏  ڇက DIίϯςφ ΅͘Β͸ڇကΛఆٛ

  55. %*  DI Container? Service Locator?

  56. 4FSWJDF-PDBUPS  class FriedRice val friedRice = FriedRice() class BowlOFRice(val

    di: DIContainer){ @Inject lateinit var rice: Rice @Inject lateinit var topping: Topping init{ di.inject() } } //オブジェクトを入れる val beefBowl = BowlOFRice(di) ※ઃܭ࣍ୈͰνϟʔϋϯ΋DIԽͰ͖·͢
  57. 4FSWJDF-PDBUPS  ґଘؔ܎ͷهड़͕ΊΜͲ͘ͳͬͯ4FSWJDF-PDBUPSʹ
 ͯ͠͠·͏ w͋ΕʁͦͷΦϒδΣΫτͬͯ
 %*$POUBJOFSͬͯؔ܎͋Γ·͚ͨͬ͠ʁ wςετ͢Δͱ͖ʹ%*$POUBJOFS͕ͳ͍ͱςετͰ͖ͳ͍ w୯७ʹ%*$POUBJOFS෼ͷґଘؔ܎͕૿͑ͯ͠·ͬͨ w͜Ε͔Β঺հ͢Δ%*$POUBJOFS͸
 4FSWJDF-PDBUPSͱͯ͠ѻ͍΍͍͢ͷͰ஫ҙ͕ඞཁ

  58. %*  Android DI: Dagger2?

  59. %*ͷ֓೦ͷΘΓʹෳࡶ  wίϯϙʔωϯτɺαϒίϯϙʔωϯτɺϞδϡʔϧɺείʔ ϓΛద੾ʹఆٛ͢Δͷେม w%*ͷྖҬ͔Β"OESPJEྖҬʹ౿ΈࠐΜͰ͖͍ͯΔ w"DUJWJUZ 'SBHNFOU͕ੜ੒͞ΕͨޙɺͰ͔ࠩ͠͠ࠐΊͳ͍΋ ͷఆ͕ٛ໘౗ wLBQUͱ%BHHFSͱͷ૬ੑ͕ѱ͍ wLWTTDIFNBͳͲͰ࡞ΒΕΔΫϥεΛ1SPWJEFSͰ͖ͳ͍ɻʢ)PMEFS

    ࡞Ε͹Մೳʣ
  60. ,PUMJOͳΒҧ͏ํ๏͕͋Δ͔΋  %FMFHBUJPOɺ%FMFHBUFE1SPQFSUJFTΛ࢖͑͹΋ͬ ͱ͏·͘Ͱ͖Δ͔΋ class Delegate {
 operator fun getValue(thisRef:

    Any?, property: KProperty<*>): String {
 return "$thisRef, thank you for delegating '${property.name}' to me!"
 }
 
 operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
 println("$value has been assigned to '${property.name} in $thisRef.'")
 }
 } 
 class Example {
 var hoge: String by Delegate()
 }
  61. %*  Kotlin + Android DI: Kodein

  62. ,PEFJO  w,PUMJO੡ wLBQUΛ࢖Θͳ͍ͷͰɺϏϧυ஗͘ͳΒͳ͍ w,PUMJOͷػೳΛ͏·͘࢖ͬͯΔ w%FMFHBUJPOΛ࢖ͬͯɺ͏·͘஫ೖ͍ͯ͠Δ w௚ײతͳจ๏ SalomonBrys/KodeinͷREADME.mdΑΓ

  63. ,PEFJO͕Ͱ͖Δ͜ͱ  w -B[JMZJOTUBOUJBUFZPVSEFQFOEFODJFTXIFOOFFEFE w 4UPQDBSJOHBCPVUEFQFOEFODZJOJUJBMJ[BUJPOPSEFS w &BTJMZCJOEDMBTTFTPSJOUFSGBDFTUPUIFJSJOTUBODFPS QSPWJEFS w

    &BTJMZEFCVHZPVSEFQFOEFODZCJOEJOHTBOE SFDVSTJPOT SalomonBrys/KodeinͷREADME.mdΑΓ
  64. ,PEFJO͕Ͱ͖Δ͜ͱ  w -B[JMZJOTUBOUJBUFZPVSEFQFOEFODJFTXIFOOFFEFE w 4UPQDBSJOHBCPVUEFQFOEFODZJOJUJBMJ[BUJPOPSEFS w &BTJMZCJOEDMBTTFTPSJOUFSGBDFTUPUIFJSJOTUBODFPS QSPWJEFS w

    &BTJMZEFCVHZPVSEFQFOEFODZCJOEJOHTBOE SFDVSTJPOT SalomonBrys/KodeinͷREADME.mdΑΓ •ඞཁͳ࣌ʹΠϯελϯεԽ •providerʹ
 ΫϥεɺΠϯλʔϑΣʔεɺΠϯελϯεΛઃఆͰ͖ΔΑ
  65. .PEVMFఆٛ  Kodein.Module { bind<型>(Qualifier) with singleton { … }

    bind<型>(Qualifier) with provider { … } bind<型>(Qualifier) with instance ( … ) } • Dagger2ͷModuleͱಉ͡ • KotlinͷػೳΛϑϧʹ࢖͍ͬͯͯจ๏ͰಡΈ΍͍͢ • infixɺϥϜμলུɺϨγʔόʔࢦఆϥϜμ
  66. .PEVMFྫ  object NetworkModule { val module = Kodein.Module {

    bind<OkHttpClient>() with singleton { OkHttpClient.Builder().build() } bind<Converter.Factory>() with singleton { GsonConverterFactory.create() } bind<Retrofit>() with singleton { Retrofit.Builder() .baseUrl(BuildConfig.GITHUB_ENDOPOINT) .addConverterFactory(instance()) .client(instance()).build() } } }
  67. .PEVMFྫ  object NetworkModule { val module = Kodein.Module {

    bind<OkHttpClient>() with singleton { OkHttpClient.Builder().build() } bind<Converter.Factory>() with singleton { GsonConverterFactory.create() } bind<Retrofit>() with singleton { Retrofit.Builder() .baseUrl(BuildConfig.GITHUB_ENDOPOINT) .addConverterFactory(instance()) .client(instance()).build() } } }
  68. ,PEFJOͷఆٛ  • Dagger2ͷComponentͱಉ͡ • ࢖༻͢ΔϞδϡʔϧΛఆٛ͢Δ class App : Application(),

    KodeinAware { override val kodein: Kodein = Kodein { bind<Context>() with instance(this@App) import(NetworkModule.module) import(PresentationModule.module) } }
  69. *OKFDU  class MVPActivity : AppCompatActivity(), GithubView { val binding

    by lazy { DataBindingUtil.setContentView<…>(this, R.layout…) } val injector: KodeinInjector = KodeinInjector() val presenter: GithubPresenter by injector.instance() override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) injector.inject(Kodein { extend(kodein) bind<GithubView>() with instance(this@MVPActivity) }) binding.searchBtn.setOnClickListener { presenter.search(binding.userEdit.text.toString()) } } }
  70. %*  Dagger2 ͱ Kodein ൺֱ

  71. %BHHFSͱ,PEFJO  ,PEFJO %BHHFS ґଘؔ܎Λ LBQUͰੜ੒ ෆཁ ඞཁ BQUͰੜ੒͞Εͨ΋ͷ JOKFDU

    ̋ ˚ )PMEFSΛ࡞ΔͳͲ޻෉͕ඞཁ ґଘؔ܎ͷ Τϥʔ ࣮ߦ࣌ ίϯύΠϧ࣌ είʔϓ ̋ ̋ /BNFE 2VBMJpFS ̋ ̋
  72. ґଘؔ܎͕͓͔͍࣌͠ͷΤϥʔ  w%BHHFSͷ৔߹͸ɺίϯύΠϧ࣌ʹΤϥʔ wBQUͰੜ੒͢ΔͷͰɺґଘؔ܎͕͓͔͍͠৔߹ʹ͸ίϯύΠϧͰ͖ ·ͤΜ w,PEFJOͷ৔߹͸ɺ࣮ߦ࣌ʹΤϥʔ w.BQΈ͍ͨͳ΋ͷʹɺΦϒδΣΫτΛಥͬࠐΜͰऔΓग़ͯ͠Δ͚ͩ ͳͷͰɺJOKFDU͢Δͱ͖ʹͭͬ͜·Ε͍ͯΔͷ͔Ͳ͏͔͸ɺ࣮ߦ͞ ΕΔ·ͰΘ͔Βͳ͍ͨΊͰ͢

  73. %*·ͱΊ  w%*πʔϧΛ%BHHFSҎ֎ͷબ୒΋͋Δ͔΋ w%FMFHBUJPOΛ࢖ͬͯ%*Λ࣮ݱͰ͖ͦ͏ w,PUMJO͕"OESPJE։ൃݴޠͱͯ͠ೖͬͨ͜ͱͰఆ൪ϥΠϒϥ Ϧͷมಈ͕͋Δ͔΋͠Εͳ͍ʜ

  74.  KotlinͰշదAndroid։ൃΛʂ

  75. None