Java Do でしょう #20 [Javaでも/それ以外でも] データアクセスについて聞きたい・話したい! https://javado.connpass.com/event/251865/ にて発表しました
Twitter #javado , slido #1231084Records の使い⽅はこれでいいの? をみんなで考えたい山川広人 (@gishi_yama)JavaDo, 公立千歳科学技術大学1
View Slide
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)適応型学習支援システムの開発、活用 レポート内の話しことば診断システムの開発大学・小学校・地域でのプログラミング教育の実践(最近は学生とドメイン駆動設計にモブワークで挑戦するのが楽しい)
Twitter #javado , slido #1231084Java 17 から Records が LTS版のJDKで正式対応にみなさん使ってますか?3
Twitter #javado , slido #1231084Summary よりEnhance the Java programming languagewith records, which are classes thatact as transparent carriers forimmutable data.⇒ (タプルのように) イミュータブルなデータを 中身が分かりやすく運送する役割のクラスJEP 395: Records4画像等引用 https://openjdk.org/jeps/395https://amz.run/5puo, https://amz.run/5pup, https://amz.run/5puk,
Twitter #javado , slido #1231084Goals•シンプルな値の集合を表現する(オブジェクト指向のセオリー上の)工夫である•拡張可能な手法よりも開発者のイミュータブルなデータのモデリングへの注力を支援する•equalsやgetter/setterのような、フィールドに基づくメソッドを自動実装する•Javaのこれまでの型システムやそれとの互換性の維持して利用できるようにする Non-Goals•クラスを簡単に宣言できるように見えるが、「クラス宣言のための面倒なお決まりの書き方」のためのものではない。特に、Java Beansのようなミュータブルなクラスの問題は手がけない。•POJOのクラスの宣言を効率化するためによく使われるコード生成機能を追加するものではない⇒ lombokなどの代わりではないし、 Kotlin(がJavaの不便や不足を補うという側面で見た場合)のデータクラスとも細部はちょっと違うRecords の⽬指すゴールと⽬指さないノンゴール(超訳)5 引用等:https://openjdk.org/jeps/395
Twitter #javado , slido #1231084Records の宣⾔⽅法6↑から生成されたインスタンスは、 右のコードと同等のフイールド・メソッドをもったクラスから生成されたもののように利用できる。ただし、以下のようなルールがある。• 継承できない(スーパー/サブクラスになれない)• 暗黙的finalで、abstract クラスにできない• フィールドはfinalになる• インスタンスフィールドやインスタンスイニシャライザは追加できない(それ以外は追加可能)• 自動生成されるメソッドはOverrideできる• インターフェースを実装(implements)できる ...など詳しくはこのあたりがわかりやすい https://docs.oracle.com/javase/jp/17/language/records.html引用等:https://openjdk.org/jeps/395
Twitter #javado , slido #1231084例えば、JSONのシリアライズ・デシリアライズ用のクラスを作りたい時 ⇒ ドメインモデルや本質的な処理には実はあまり必要のない、 WEB-API(からもらうJSON)の都合に合わせたクラスを増やさなくて良くなった例えば、DBのいろんな検索クエリの結果をマッピングするクラスなども気軽に作れる様になった (※ Spring JDBCの場合、ちょっと RawMapper の取り回しは必要ある感じ)外部とのデータのやり取りにすごく便利に使える7API接続用のクラスの中に、シリアライズ・デシリアライズ用のレコードを複数宣言できる ⇒ .java も増えない!
Twitter #javado , slido #1231084例えば、値オブジェクト や ドメイン層のオブジェクト を作りたい時 Records で宣言してよい or ちゃんとクラスを宣言すべき のどちらにするか? ⇒ フィールドのデータを外部に渡すかどうかは、最初の判断材料 ⇒ あとは必要なメソッド等をみて判断。 本当に欲しいのはlombokの@withやkotlinのデータクラスだったということもよくあるこういう時にはちょっと悩む8値オブジェクトやファーストクラスコレクションはRecords でも良い場合もありそう ※アクセッサで新規インスタンスや不変リスト返すかなど、 副作用に対し防御的なコードは@Overrideで対応 (ただ、段々面倒になりクラスで良くね?になってくる)Records にする? 🤔 ロジックが主の場合は 通常のクラスの方がよいのでは
Twitter #javado , slido #1231084Recordsはこれまでの型システムやそれとの互換性の維持して利用できる ⇒ Records を使う必要がない・使うべきではない時であってもコード上は書けてしまうたとえば、SpringのServiceやRepositoryも書こうと思えば record にできる(、し動く)...やろうと思えばこういうこともできてしまう9記述量減って宣言が楽かも? と一瞬錯覚するけど...外部から huga() で hugaの参照にアクセスできる様に なっているけど必要ある?equals/hashCode も実装される けど、Serviceで同値性を判断したい 場合はむしろ稀では...?思い出そうRecordsのNon Goal:「面倒なお決まりの書き方」 のためのものではない!
Twitter #javado , slido #1231084適切な利⽤には...他の仕組みとの違いを意識する10Kotlinやlombokなどのコード生成で生成されるものと、重なっているところも類似点もある ⇒ どう使い分けるか・適切に利用するかは、 それぞれのドキュメントやJEPを読んで、その仕組みの理念を意識する必要があるのではKotlinのデータクラスは「データから標準・ユーテリティ的な仕組みをメカニカルに生成する」 lomonkは「アノテーション駆動のコード生成でボイラープレートコードを削減する」 Recordsは「(タプルのように)イミュータブルなデータを中身が分かりやすく運送する」Java’s Records vs Kotlin’s Data Classes引用・参考: https://stackoverflow.com/questions/64468267/java-records-vs-kotlin-data-classes https://medium.com/javarevisited/javas-records-vs-kotlin-s-data-classes-b3fef851155a
Twitter #javado , slido #1231084Records は (タプルのように)イミュータブルなデータを中身が分かりやすく運送する役割のために、 既存のクラスやその宣言との互換性を意識せず利用できるようにした仕組み簡単にクラスを宣言できる様に見えるけど、 全ての用途のクラスの宣言の面倒臭さを解決するためのものではない ⇒ 意外とピッタリ使える部分は少ない?(シリアライズ・デシリアライズ・マッピングは ) ⇒ 値オブジェクトやファーストクラスコレクションなどに使える部分もある 自分達のコードや設計に必要なものはどれなのか、結果が似る仕組みとの違いを把握して選ぶ ・例えばKotlinのデータクラスや、lombokの様なコード生成ツール ⇒ Records があればいらなくなるわけではないし、Records だけでは不足(守備範囲が違う)まとめ11💯