質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

4回答

3031閲覧

エラー情報を呼び出し元に知らせる時、返り値か例外どちらで知らせるべきですか?

jimyo

総合スコア243

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2017/10/04 15:12

編集2017/10/04 15:15

次のようなメソッドを考えます。

registerUser(User user)

  • このメソッドはUserをデータストアに登録する
  • 発生しうるエラーには3種類あり次の通りである
  • 「データストアへの登録の失敗」
  • 「ユーザーネームの重複」
  • 「パスワードに無効な文字が使われている」

registerUser メソッドを呼び出す処理の中で、登録ができたのかどうかを判定したいです。
登録に失敗している場合、エラーの種別に応じてその後の処理を変更したいです。(例: ユーザーネームが重複している場合、「ユーザーネームが重複しているので変更してください」と促したい)

このような処理を行う場合次のような3つのフローが考えられます。

  1. registerUserint またはエラーオブジェクトを返す。呼び出し元は返ってきた数値またはオブジェクトからエラー情報を読み取る
  2. registerUser はエラーが起きた場合、それぞれのエラーに対応する例外を投げる。呼び出し元は try-catch 文で処理を囲い、3種類の例外をcatchし処理を行う
  3. 新しいメソッド checkDuplicatedUsername checkValidPassword を用意し、それぞれ確認を行ってから registerUser を呼び出す。

個人的には1が好みなのですがJava的にはどうなのでしょうか?
以下2、3の私が考えたデメリットです。

2のデメリット

  • 確実にエラーが起きないような場合でも、呼び出すたびに try-catch しなければならず冗長
  • この方法で統一した場合コードが膨大になる

3のデメリット

  • registerUser を呼び出すルールがメソッド内で閉じていない。(あらかじめ2つのメソッドを呼び出す前提となっているため、仕様を詳しく知らない人に不親切)

よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答4

0

発生しうるエラーには3種類あり

全体的なつくりがどうなっているか次第な面もありますが、
ひとつの関数で扱うエラー内容ではないのかなあ
という気がします。

とりあえず、「ユーザーネームの重複」と
「パスワードに無効な文字が使われている」は
この処理にくる前にチェックしておき、
ここでのエラーは純粋にデータストア関連の
エラーのみとするのかなあ。
自分だったら、ですが。

投稿2017/10/04 21:59

takasima20

総合スコア7458

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

大きく分けて例外処理は、
実装者が想定できる例外と、想定できない例外があります。

例えばDB登録の際、NUllが非許容の箇所がNullでわたってきた場合は、
事前に想定できる例外です。

主に登録時の仕様と、データ参照時の削除されていたデータ等の排他処理は想定できます。

逆に想定できないパターンとして、
普段は上手くいくのに、IEやChoromeのUpdateで突如原因不明で実行できなくなったりする場合の例外処理もあります。

そういったものはTry catchで取れるようにするのがいいと思います。

そもそもとして、ユーザ登録やパスワードのチェックは必須のチェックであるから、
私はパターン3が良いと思います。

checkDuplicatedUsername(hoge.UserId)
checkValidPassword (hoge.UserPassword)
try
registerUser (hoge)
catch

というような作りで問題ないかと思います。(上のコードは適当です)

投稿2017/10/05 00:46

編集2017/10/05 00:48
King_of_Flies

総合スコア382

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

例外を上手く扱うようにした2がいいと思います。想像するにユーザ登録はI/Oが伴う操作なので例外が100%発生し得ないような呼び出しはあり得ないと思います。

「データストアへの登録の失敗」の多くはファイルを開けなかったりネットワークが不通だったりと既存の例外に起因する失敗だと想像します。

「ユーザーネームの重複」はユニーク制約バイオレーション系のデータベースレベルの例外に基づくと推測します。

「パスワードに無効な文字が使われている」は入力値のバリデーションルール違反でしょう。

私ならregisterUserは低レイヤの例外を各種リカバリプランを示すユーザ定義の例外にすげ替えるような処理を入れた失敗を前提としたメソッドにして、コードの簡略化のために別のreliableRegisterUserなどで各種リカバリ処理を隠匿する実装にします。

投稿2017/10/04 17:02

YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「Java的にどうか」と聞かれると答え方に困りますが、1がいいのではないでしょうか。
そのメソッドの結果がエラー3種類+登録成功の4種類と決まっているのであれば、Enumを使うのも手かと。
結果によってやることが似ている(例:特定のメッセージを表示する)のであればなおさらEnumは使えます。

2の例外はtry-catchが面倒というのならRuntimeException継承例外にしてしまえば、必要なところだけ囲めば済みます。

投稿2017/10/04 15:58

swordone

総合スコア20651

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問