$30 off During Our Annual Pro Sale. View Details »

XMLのObject Mapping

XMLのObject Mapping

XMLとかのObjectMapperを作るときの、3つのアプローチについて

kobito-kaba

June 21, 2018
Tweet

More Decks by kobito-kaba

Other Decks in Programming

Transcript

  1. XMLのObject Mapping
    Yahoo! JAPAN 森洋之

    View Slide

  2. 森 洋之 @moridroid

    View Slide

  3. 森 洋之 @moridroid
    Yahoo! JAPAN Androidアプリ黒帯
     (こういうところで話す仕事)

    View Slide

  4. 森 洋之 @moridroid
    Yahoo! JAPAN Androidアプリ黒帯
     (こういうところで話す仕事)
    ヤフオク!のアプリ担当

    View Slide

  5. goo.gl/fW2YPh

    View Slide

  6. View Slide

  7. はじめます

    View Slide

  8. Codable

    View Slide

  9. {
    "name": "hoge",
    "sex": 0,
    "birthday": "19900530",
    "mail_address": "[email protected]"
    }
    struct User: Codable {
    let name: String
    let sex: Int
    let birthday: String
    let mail_address: String
    }
    JSON struct

    View Slide

  10. View Slide

  11. View Slide

  12. Gson

    View Slide

  13. Gson
    Jackson

    View Slide

  14. Gson
    Jackson
    Moshi

    View Slide

  15. Gson
    Jackson
    Moshi
    SimpleXML

    View Slide

  16. Gson
    Jackson
    Moshi
    SimpleXML
    JAXB

    View Slide

  17. 基本的なロジック

    View Slide


  18. Taro
    18
    Japan

    View Slide

  19. User
    - name uninitialized
    - age uninitialized
    - locale uninitialized

    Taro
    18
    Japan

    val user = User( )

    View Slide

  20. User
    - name ”Taro”
    - age uninitialized
    - locale uninitialized

    Taro
    18
    Japan

    user.name = “Taro”

    View Slide

  21. User
    - name ”Taro”
    - age 18
    - locale uninitialized

    Taro
    18
    Japan

    user.age = 18

    View Slide

  22. User
    - name ”Taro”
    - age 18
    - locale ”Japan”

    Taro
    18
    Japan

    user.locale = “Japan”

    View Slide

  23. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized

    View Slide

  24. View Slide

  25. data class
    Excellent!!

    View Slide

  26. data class User(val name : String,
    val age : Int,
    val locale : String)

    View Slide

  27. data class User(val name : String,
    val age : Int,
    val locale : String)
    コンストラクタ

    View Slide

  28. data class User(val name : String,
    val age : Int,
    val locale : String)
    コンストラクタ
    イミュータブル

    View Slide

  29. data class User(val name : String,
    val age : Int,
    val locale : String)
    コンストラクタ
    イミュータブル
    非null

    View Slide

  30. 基本的なロジック
    again!!

    View Slide

  31. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized

    View Slide

  32. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized
    空のコンストラクタ無い

    View Slide

  33. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized
    イミュータブル
    空のコンストラクタ無い

    View Slide

  34. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized
    イミュータブル
    空のコンストラクタ無い
    非null

    View Slide

  35. User
    - name ”Taro”
    - age 18
    - locale ”Japan”
    User
    - name uninitialized
    - age uninitialized
    - locale uninitialized
    イミュータブル
    空のコンストラクタ無い
    非null
    考え方が合わない

    View Slide

  36. 無理に使うなら

    View Slide

  37. data class User(var name : String?,
    var age : Int?,
    var locale : String?)

    View Slide

  38. data class User(var name : String?,
    var age : Int?,
    var locale : String?)
    ミュータブル

    View Slide

  39. data class User(var name : String?,
    var age : Int?,
    var locale : String?)
    ミュータブル nullable

    View Slide

  40. data class User(var name : String?,
    var age : Int?,
    var locale : String?)
    ミュータブル nullable
    糞プロパティ
    爆誕

    View Slide

  41. じゃあどうするか

    View Slide

  42. JSON

    View Slide

  43. JSON
    Moshi

    View Slide

  44. XML

    View Slide

  45. XML
     見なかった
     ことにする

    View Slide

  46. View Slide

  47. XML
     自分で作る

    View Slide

  48. 3つのアプローチ

    View Slide

  49. 1. Reflection

    View Slide


  50. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    View Slide


  51. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    data class Inbox(
    val name : String,
    val mails : List)
    data class Mail(
    val title : String,
    val body : String,
    val from : User)
    data class User(
    val name : String,
    val address : String)

    View Slide


  52. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    data class Inbox(
    val name : String,
    val mails : List)
    data class Mail(
    val title : String,
    val body : String,
    val from : User)
    data class User(
    val name : String,
    val address : String)
    inline fun fromXML(xml : InputStream) : T? {
    // ...
    }

    View Slide

  53. inline fun fromXML(xml : InputStream) : T? {
    // ...
    }
    val inbox = fromXML(inpustStream)

    View Slide

  54. Mail
    - title : String
    - body : String
    - from : User
    User
    - name : String
    - address : String
    Inbox
    - name : String
    - mail : List

    View Slide


  55. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値

    View Slide


  56. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name
    - Mails

    View Slide


  57. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails

    View Slide


  58. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [ ]

    View Slide

  59. index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2]
    2 Mail
    - title
    - body
    - User

    受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    View Slide

  60. index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2]
    2 Mail
    - title
    - body
    - User

    受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    View Slide


  61. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2]
    2 Mail
    - title 主人がオオアリクイに …
    - body いきなりのメール失礼 …
    - User 3
    3 User
    - name
    - address

    View Slide


  62. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2]
    2 Mail
    - title 主人がオオアリクイに …
    - body いきなりのメール失礼 …
    - User 3
    3 User
    - name
    - address

    View Slide


  63. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2]
    2 Mail
    - title 主人がオオアリクイに …
    - body いきなりのメール失礼 …
    - User 3
    3 User
    - name オオアリクイ
    - address [email protected]

    View Slide


  64. 受信箱


    主人がオオアリクイに…
    いきなりのメール失礼…

    オオアリクイ
    [email protected]





    index オブジェクト プロパティ 値
    1 Inbox
    - name 受信箱
    - Mails [2, 4, 6, ...]
    2 Mail
    - title 主人がオオアリクイに …
    - body いきなりのメール失礼 …
    - User 3
    3 User
    - name オオアリクイ
    - address [email protected]
    4 Mail
    - title 私はチンパンジーです。
    - body はじめまして。早苗と …

    View Slide

  65. Mail
    - title : String
    - body : String
    - from : User
    User
    - name : String
    - address : String
    Inbox
    - name : String
    - mail : List

    View Slide

  66. Reflection

    View Slide

  67. Reflection
    Pros 作るのが楽

    View Slide

  68. Reflection
    Pros 作るのが楽
    Cons Reflectionであること

    View Slide

  69. Reflection
    Pros 作るのが楽
    Cons Reflectionであること
         ・遅い
         ・kotlin-reflect、でかい

    View Slide

  70. 2. APT

    View Slide

  71. View Slide

  72. クラス追加

    View Slide

  73. interface XMLAdapter {
    fun fromXml(xml : InputStream) : T?
    }

    View Slide

  74. inline fun xmlAdapter( ) : XMLAdapter {
    // ...
    }
    interface XMLAdapter {
    fun fromXml() : T?
    }

    View Slide

  75. data class Inbox(
    val name : String,
    val mails : List)
    data class Mail(
    val title : String,
    val body : String,
    val from : User)
    data class User(
    val name : String,
    val address : String)

    View Slide

  76. @XmlClass
    data class Inbox(
    val name : String,
    val mails : List)
    @XmlClass
    data class Mail(
    val title : String,
    val body : String,
    val from : User)
    @XmlClass
    data class User(
    val name : String,
    val address : String)

    View Slide

  77. @XmlClass
    data class Inbox(
    val name : String,
    val mails : List)
    @XmlClass
    data class Mail(
    val title : String,
    val body : String,
    val from : User)
    @XmlClass
    data class User(
    val name : String,
    val address : String)
    class Inbox_XmlAdapter : XmlAdapter
    class Mail_XmlAdapter : XmlAdapter
    class User_XmlAdapter : XmlAdapter

    View Slide

  78. inline fun xmlAdapter( ) : XMLAdapter {
    return Class.forName(“${T::class.name}_XmlAdapter”).newInstance()
    }

    View Slide

  79. val adapter = xmlAdapter()
    val inbox = adapter.fromXml(inputStream)
    inline fun xmlAdapter( ) : XMLAdapter {
    return Class.forName(“${T::class.name}_XmlAdapter”).newInstance()
    }

    View Slide

  80. APT

    View Slide

  81. APT
    Pros Reflectionじゃないこと
         拡張性高め

    View Slide

  82. APT
    Pros Reflectionじゃないこと
         拡張性高め
    Cons めんどくさい
         難読化したらまずい

    View Slide

  83. 3. Transform API

    View Slide

  84. View Slide

  85. バイトコード変換

    View Slide

  86. goo.gl/u5XHJi

    View Slide

  87. inline fun xmlAdapter( ) : XMLAdapter {
    return when(T::class) {
    Inbox::class -> Inbox_XmlAdapter()
    Mail::class -> Mail_XmlAdapter()
    ...
    }
    }

    View Slide

  88. Transform API

    View Slide

  89. Transform API
    Pros 難読化しても影響ない

    View Slide

  90. Transform API
    Pros 難読化しても影響ない
    Cons 超めんどくさい
         バイトコードだから…

    View Slide

  91. まとめ

    View Slide

  92. つくろうぜ!
    オブジェクトマッパー

    View Slide

  93. View Slide

  94. おしまい

    View Slide