Slide 1

Slide 1 text

© DMM © DMM CONFIDENTIAL 例外と向き合う #dmm_android勉強会 電子書籍事業部 森 幸浩 2023/06/20

Slide 2

Slide 2 text

© DMM 2 名前 森 幸浩 (もり ゆきひろ) 所属 電子書籍事業部 Androidチーム 自己紹介 • 約3年電子書籍事業部のAndroidチームで開発 • リファクタリングや新機能開発を担当

Slide 3

Slide 3 text

© DMM 3 ■ 例外についての言語仕様 - Java言語での例外 - Kotlin言語での例外 - 検査例外がなくなった背景 ■ Kotlinの例外処理のアプローチ - 非検査例外 - エラー状態の定義 ■ DMMブックスでの例外処理のアプローチ - 非検査例外の独自定義 目次

Slide 4

Slide 4 text

© DMM 例外についての言語仕様

Slide 5

Slide 5 text

© DMM Java言語での例外 5 検査例外 ■ コンパイル時にtry-catchがされているかを チェックする 非検査例外 (RuntimeException) ■ コンパイル時にtry-catchがされているかを チェックしない

Slide 6

Slide 6 text

© DMM Java言語での例外 6 検査例外 ■ コンパイル時にtry-catchがされているかをチェックする

Slide 7

Slide 7 text

© DMM Java言語での例外 7 非検査例外 (RuntimeException) ■ コンパイル時にtry-catchがされているかをチェックしない

Slide 8

Slide 8 text

© DMM Java言語での例外 8 検査例外 ■ コンパイル時にtry-catchがされているかを チェックする 例外処理をプログラマに強制する 非検査例外 (RuntimeException) ■ コンパイル時にtry-catchがされているかを チェックしない 例外処理はプログラマの判断に任される

Slide 9

Slide 9 text

© DMM Kotlin言語での例外 ところが... Kotlinではコンパイルエラーがでない 9

Slide 10

Slide 10 text

© DMM Kotlin言語での例外 Kotlinでは検査例外が廃止された 翻訳 Kotlinには検査例外がありません。ここには多くの理由がありますが、なぜそうしたのかを説明する簡 単な例を示します。 10 https://kotlinlang.org/docs/exceptions.htm l#checked-exceptions ↑公式ドキュメントより抜粋

Slide 11

Slide 11 text

© DMM Kotlin言語で検査例外がなくなった背景

Slide 12

Slide 12 text

© DMM 検査例外がなくなった背景 検査例外はコンパイル時点で処理すべき例外の漏れを防げる - 生産性が上がる - 品質向上につながる と思われていたが... 12

Slide 13

Slide 13 text

© DMM 検査例外がなくなった背景 小規模なシステムであれば 発生箇所からハンドリングまでの距離が近いため複雑化しない 13

Slide 14

Slide 14 text

© DMM 検査例外がなくなった背景 14 小規模なシステムであれば 考慮しなければいけない例外の数も限定的

Slide 15

Slide 15 text

© DMM 検査例外がなくなった背景 システムの規模が大きくなると 発生箇所とハンドリングまでの距離が遠く中間のビジネスロジックが 複雑化 15

Slide 16

Slide 16 text

© DMM 検査例外がなくなった背景 システムの規模が大きくなると 複雑化したビジネスロジックでは考慮しなければならない例外が 爆発的に増加 16

Slide 17

Slide 17 text

© DMM 検査例外がなくなった背景 中間層ではthrows項で発生する例外の明示が必要なため 大量の例外宣言によりコードの可読性が落ち、生産性が落ちる 17

Slide 18

Slide 18 text

© DMM 検査例外がなくなった背景 結果として 検査例外を握りつぶしたり... 18

Slide 19

Slide 19 text

© DMM 検査例外がなくなった背景 結果として 非検査例外に変えたりする実装が横行し品質も上がらない 19

Slide 20

Slide 20 text

© DMM 検査例外がなくなった背景 検査例外はコンパイル時点で処理すべき例外の漏れを防げる - 生産性が上がる - 品質向上につながる と思われていたが、規模が大きくなると - 生産性が下がり - 品質向上もしない (握り潰しなどの横行により) 20

Slide 21

Slide 21 text

© DMM Kotlin言語での例外処理のアプローチ

Slide 22

Slide 22 text

© DMM Kotlin言語での例外処理のアプローチ 非検査例外 Java言語の非検査例外と同様に 非検査例外をthrowする方法 実行側でtry-catchにより ハンドリングする 22

Slide 23

Slide 23 text

© DMM Kotlin言語での例外処理のアプローチ 非検査例外 メリット - シンプルに書ける - 可読性が高い デメリット - ハンドリングが漏れると クラッシュに繋がる 23

Slide 24

Slide 24 text

© DMM Kotlin言語での例外処理のアプローチ エラー状態の定義 例外を取りうる操作の場合 実行結果にエラー状態を定義する 24

Slide 25

Slide 25 text

© DMM Kotlin言語での例外処理のアプローチ エラー状態の定義 メリット - 網羅的に書ける デメリット - 実行結果の型定義が増える - 予め例外を想定する必要がある 25

Slide 26

Slide 26 text

© DMM DMMブックスアプリでの例外処理のアプローチ

Slide 27

Slide 27 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 文脈単位で非検査例外を独自定義 個別に関心事がある例外をsealedクラスの子クラスで定義 27

Slide 28

Slide 28 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 Repository層で変換 親クラスで伝播する 28

Slide 29

Slide 29 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 Repository層で独自定義の例外に変換して上位のレイヤーに伝播していく 29

Slide 30

Slide 30 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 UseCase層など中間層では集約された例外で扱うため 記述量が抑えられる 30

Slide 31

Slide 31 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 ViewModel層で表示内容に変換する際に集約化された詳細を確認する 31

Slide 32

Slide 32 text

© DMM DMMブックスアプリでのアプローチ 非検査例外を独自定義 - 関心ごとのある例外をsealedクラスで定義 → 網羅性をある程度 確保 - 文脈単位で定義することで伝播する例外を集約 → 中間層での可読性の向上 といった感じで 例外を階層化し集約することで複雑さを整理することにしました 32

Slide 33

Slide 33 text

© DMM まとめ

Slide 34

Slide 34 text

© DMM まとめ ■ 例外についての言語仕様 Java言語では検査例外があるがKotlinでは検査例外がない 検査例外はスケールが大きくなると生産性が落ち、品質向上につながらない そのためKotlinでは検査例外が廃止された ■ Kotlinの例外処理のアプローチ 非検査例外 可読性は上がるが 網羅性に問題あり エラー定義 網羅性はあるが 定義量が多くなる ■ DMMブックスでの例外処理のアプローチ 非検査例外を独自に階層化し集約 関心事のある例外のみを定義することで網羅性と可読性をあげた 34

Slide 35

Slide 35 text

© DMM ご静聴ありがとうございました