B-Teck!

お仕事からゲームまで幅広く

【Kotlin】data classにJavaから呼び出せるBuilderを用意する

はじめに

Kotlinには名前付き引数を利用することができるので、
コンストラクタに渡す引数をわかりやすく記述することができます。

Person(
  name = "taro",
  age = 20
)

しかし、JavaとKotlinが混在している場合は、Javaからは名前付き引数の仕組みを利用できません。
そうした場合には、KotlinのclassにBuilderを定義することで、
Java、Kotlin両方から扱いやすいclassにすることができます。

data classにBuilderを定義した例

以下の例はKotlinのdata classにBuilderを定義したものです。

data class Person(
    val name : String,
    val age : Int
) {
    class Builder(
        private var name : String? = null,
        private var age : Int? = null
    ) {
        fun name(name : String) = this.also { it.name = name }
        fun age(age : Int) = this.also { it.age = age }
        fun build() = Person(this.name!!, this.age!!)
    }
    companion object {
        @JvmStatic
        fun builder() = Builder()
    }
}

Kotlin・Javaからの呼び出し方

このdata classは、Kotlinからは冒頭と同様に下記の形でインスタンスを作成できますし、

Person(
  name = "taro",
  age = 20
)

Javaからはこのように呼ぶことができます。

Person.builder()
  .name("taro")
  .age(20)
  .build();

より良い書き方があるかもしれないので、ご存知の方はコメントなどでお知らせください。

【雑記】29歳になりました。

さて、まぁ掲題の通りなんですが、29歳になりました。
(この記事は予約投稿なので書いているときはまだ28ですが) ついに20代最後の歳ですね。

前置き

元号が令和に切り替わり、GWも折り返しを過ぎちゃいましたね。
私は連休中、Androidの勉強をしたり、普段できていない部屋の片付けをしたりしていました。
本当は最近一番ハマっているストVもやりたいんですが、なかなかまとまった時間が取れてなくて…
(IDはbeatbeat-djamです!フレンド募集してます!)

近況報告

近況ですが、

  • 仕事とかプログラミングとか
    500人未満くらいの規模の自社サービスの会社で、
    アプリのサーバーサイドをメインにいくつかのサービスを持たせてもらってます。
    毎日Kotlinが書けて楽しい!
    今年は未経験領域への挑戦として、Android勉強してアプリリリースまでしようと思ってます。
    できるといいなぁ。
    スキルセットその他の話はProfileを参照くださいな。

  • 私生活
    妻と喧嘩したり仲直りしながらも、なんとかうまくやってこれています。
    転職を機に前職より少し忙しくなったので、家庭の時間が少なくなっているのがネックです…。
    母子家庭の一人っ子、かつ大学以来一人暮らしだった自分が人と暮らすのはなかなか容易ではなく、
    今でも妻に迷惑をかけることしきりです。改善していきたいですね…。
    あとは相も変わらず金欠です。奨学金ェ…

といった感じです。

振り返りとか

思えば20代後半は決断の時期でした。
今まで人に流されて生きてきた自分が、結婚・転職と人生を変える決断を二度もしています。
どちらもいい選択だったと思っているし、決断できてよかったなと思っています。
これからの一年が30代前半を決める事になっていくと思うので、
この気持ちを一年後も持っていられるように努力を続けていきたいですね。

何はともあれ、この記事を見て頂いてる方々と結ばせていただいたご縁と共に、
また一年頑張っていこうと思っています。
引き続きいろいろご迷惑をおかけすると思いますが、仲良くしてくださいね。

ぷれぜんとこ〜な〜

以下お約束で置いているだけですがプレゼントコーナーです。

JSONからJSON Schemaを生成してYAMLに変換する

YAMLで書いてるSwaggerの定義に実装済みのAPIを記述したいが、
レスポンスの定義を手で書くのはしんどい…みたいなときに、
実際に返却しているJSONから生成できれば便利では!?と思ってやってみた。

TL;DR

  • QuicktypeでJSONからJSON Schemaを生成
  • json2yamlでJSON Schemaをyamlに変換
  • Swaggerで読み取れて便利

手順

不要そうなところは各自適宜飛ばしてください。

Quicktypeのインストール

# quicktypeインストールのための手順
# Homebrewインストール
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
# node.js(npm)インストール
brew install nodebrew
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.bash_profile
nodebrew install-binary latest # 必要に応じて変えてください
# quicktypeインストール
npm install -g quicktype

json2yamlのインストール

# json2yamlインストールのための手順
# MacはデフォルトでPython2.7がインストールされているのでそのまま使う
# (2019/04/24時点)
# pipインストール
curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py
python get-pip.py --user
rm get-pip.py 
# パスを通す
export PATH="$HOME/Library/Python/2.7/bin:$PATH"
echo 'export PATH="$HOME/Library/Python/2.7/bin:$PATH"' >> ~/.bash_profile

# json2yamlインストール
pip install json2yaml --user

実行例

あくまで食わせたJSONの定義のみを吐き出すので、実際のrequiredと正しいかとか、
細かいオブジェクトが網羅できているかはチェックが必要なので注意。

# homeにおいたresponse.jsonをschema.yamlに変換して吐き出す
quicktype response.json --lang schema | json2yaml > schema.yaml

生成元のjson

{
  "foo": [ 1, null ],
  "baz": {
    "foo": [ true, "bar" ],
    "baz": "qux"
  }
}

yaml変換後のSchema

$schema: http://json-schema.org/draft-06/schema#
$ref: '#/definitions/Test'
definitions:
  Test:
    type: object
    additionalProperties: false
    properties:
      foo:
        type: array
        items:
          anyOf:
          - type: integer
          - type: 'null'
      baz:
        $ref: '#/definitions/Baz'
    required:
    - baz
    - foo
    title: Test
  Baz:
    type: object
    additionalProperties: false
    properties:
      foo:
        type: array
        items:
          $ref: '#/definitions/Foo'
      baz:
        type: string
    required:
    - baz
    - foo
    title: Baz
  Foo:
    anyOf:
    - type: boolean
    - type: string
    title: Foo

平成最後の記事更新でした。
令和でまたお会いしましょう。