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

Records の使い方はこれでいいの?
をみんなで考えたい / Java DO #20

Records の使い方はこれでいいの?
をみんなで考えたい / Java DO #20

Java Do でしょう #20
[Javaでも/それ以外でも] データアクセスについて聞きたい・話したい!
https://javado.connpass.com/event/251865/ にて発表しました

Hiroto YAMAKAWA

August 06, 2022
Tweet

More Decks by Hiroto YAMAKAWA

Other Decks in Programming

Transcript

  1. Twitter #javado , slido #1231084
    Records の使い⽅はこれでいいの?

    をみんなで考えたい
    山川広人 (@gishi_yama)


    JavaDo, 公立千歳科学技術大学
    1

    View Slide

  2. Twitter #javado , slido #1231084 2
    公立千歳科学技術大学 情報システム工学科 専任講師

    R&D: Experimental Development of ICT Services (ex: City-Bus Tacking System)

    Learning Technology, Programming & Programmer's Education
    ⼭川広⼈
    千歳市バスロケーションシステムの開発

    (2016-2022)
    適応型学習支援システムの開発、活用 レポート内の話しことば診断システムの開発
    大学・小学校・地域でのプログラミング教育の実践(最近は学生とドメイン駆動設計にモブワークで挑戦するのが楽しい)

    View Slide

  3. Twitter #javado , slido #1231084
    Java 17 から Records が LTS版のJDKで正式対応に


    みなさん使ってますか?
    3

    View Slide

  4. Twitter #javado , slido #1231084
    Summary より


    Enhance the Java programming language
    with records, which are classes that
    act as transparent carriers for
    immutable data.


    ⇒ (タプルのように)

      イミュータブルなデータを

      中身が分かりやすく運送する役割のクラス


    JEP 395: Records
    4
    画像等引用 https://openjdk.org/jeps/395


    https://amz.run/5puo, https://amz.run/5pup, https://amz.run/5puk,

    View Slide

  5. Twitter #javado , slido #1231084
    Goals


    •シンプルな値の集合を表現する(オブジェクト指向のセオリー上の)工夫である


    •拡張可能な手法よりも開発者のイミュータブルなデータのモデリングへの注力を支援する


    •equalsやgetter/setterのような、フィールドに基づくメソッドを自動実装する


    •Javaのこれまでの型システムやそれとの互換性の維持して利用できるようにする



    Non-Goals


    •クラスを簡単に宣言できるように見えるが、「クラス宣言のための面倒なお決まりの書き方」のための
    ものではない。特に、Java Beansのようなミュータブルなクラスの問題は手がけない。


    •POJOのクラスの宣言を効率化するためによく使われるコード生成機能を追加するものではない


    ⇒ lombokなどの代わりではないし、

      Kotlin(がJavaの不便や不足を補うという側面で見た場合)のデータクラスとも細部はちょっと違う
    Records の⽬指すゴールと⽬指さないノンゴール(超訳)
    5 引用等:https://openjdk.org/jeps/395

    View Slide

  6. Twitter #javado , slido #1231084
    Records の宣⾔⽅法
    6
    ↑から生成されたインスタンスは、

    右のコードと同等のフイールド・メソッドをもったクラスか
    ら生成されたもののように利用できる。


    ただし、以下のようなルールがある。


    • 継承できない(スーパー/サブクラスになれない)


    • 暗黙的finalで、abstract クラスにできない


    • フィールドはfinalになる


    • インスタンスフィールドやインスタンスイニシャライザは追
    加できない(それ以外は追加可能)


    • 自動生成されるメソッドはOverrideできる


    • インターフェースを実装(implements)できる

    ...など
    詳しくはこのあたりがわかりやすい

    https://docs.oracle.com/javase/jp/17/language/records.html
    引用等:https://openjdk.org/jeps/395

    View Slide

  7. Twitter #javado , slido #1231084
    例えば、JSONのシリアライズ・デシリアライズ用のクラスを作りたい時


     ⇒ ドメインモデルや本質的な処理には実はあまり必要のない、

       WEB-API(からもらうJSON)の都合に合わせたクラスを増やさなくて良くなった


    例えば、DBのいろんな検索クエリの結果をマッピングするクラスなども気軽に作れる様になった

      (※ Spring JDBCの場合、ちょっと RawMapper の取り回しは必要ある感じ)


    外部とのデータのやり取りにすごく便利に使える
    7
    API接続用のクラスの中に、シリアライズ・デシリアライズ用のレコードを複数宣言できる ⇒ .java も増えない!

    View Slide

  8. Twitter #javado , slido #1231084
    例えば、値オブジェクト や ドメイン層のオブジェクト を作りたい時

     Records で宣言してよい or ちゃんとクラスを宣言すべき のどちらにするか?

      ⇒ フィールドのデータを外部に渡すかどうかは、最初の判断材料

      ⇒ あとは必要なメソッド等をみて判断。

       本当に欲しいのはlombokの@withやkotlinのデータクラスだったということもよくある
    こういう時にはちょっと悩む
    8
    値オブジェクトやファーストクラスコレクションは
    Records でも良い場合もありそう

    ※アクセッサで新規インスタンスや不変リスト返すかなど、

     副作用に対し防御的なコードは@Overrideで対応

    (ただ、段々面倒になりクラスで良くね?になってくる)
    Records にする? 🤔

    ロジックが主の場合は

    通常のクラスの方がよいのでは

    View Slide

  9. Twitter #javado , slido #1231084
    Recordsはこれまでの型システムやそれとの互換性の維持して利用できる

     ⇒ Records を使う必要がない・使うべきではない時であってもコード上は書けてしまう


    たとえば、SpringのServiceやRepositoryも書こうと思えば record にできる(、し動く)...


    やろうと思えばこういうこともできてしまう
    9
    記述量減って宣言が楽かも?

    と一瞬錯覚するけど...


    外部から huga() で

    hugaの参照にアクセスできる様に

    なっているけど必要ある?


    equals/hashCode も実装される

    けど、Serviceで同値性を判断したい

    場合はむしろ稀では...?
    思い出そうRecordsのNon Goal:


    「面倒なお決まりの書き方」

     のためのものではない!

    View Slide

  10. Twitter #javado , slido #1231084
    適切な利⽤には...他の仕組みとの違いを意識する
    10
    Kotlinやlombokなどのコード生成で生成されるものと、重なっているところも類似点もある

     ⇒ どう使い分けるか・適切に利用するかは、

      それぞれのドキュメントやJEPを読んで、その仕組みの理念を意識する必要があるのでは


    Kotlinのデータクラスは「データから標準・ユーテリティ的な仕組みをメカニカルに生成する」

    lomonkは「アノテーション駆動のコード生成でボイラープレートコードを削減する」

    Recordsは「(タプルのように)イミュータブルなデータを中身が分かりやすく運送する」
    Java’s Records vs Kotlin’s Data Classes
    引用・参考:

    https://stackover
    fl
    ow.com/questions/64468267/java-records-vs-kotlin-data-classes

    https://medium.com/javarevisited/javas-records-vs-kotlin-s-data-classes-b3fef851155a

    View Slide

  11. Twitter #javado , slido #1231084
    Records は

    (タプルのように)イミュータブルなデータを中身が分かりやすく運送する役割のために、

    既存のクラスやその宣言との互換性を意識せず利用できるようにした仕組み


    簡単にクラスを宣言できる様に見えるけど、

    全ての用途のクラスの宣言の面倒臭さを解決するためのものではない

    ⇒ 意外とピッタリ使える部分は少ない?(シリアライズ・デシリアライズ・マッピングは )

    ⇒ 値オブジェクトやファーストクラスコレクションなどに使える部分もある



    自分達のコードや設計に必要なものはどれなのか、結果が似る仕組みとの違いを把握して選ぶ

    ・例えばKotlinのデータクラスや、lombokの様なコード生成ツール

     ⇒ Records があればいらなくなるわけではないし、Records だけでは不足(守備範囲が違う)
    まとめ
    11
    💯

    View Slide