お世話になります。
メソッド、関数の引数チェックを呼び出し先で行うか、呼び出し元で行うかの設計で悩んでいます。
例えば、nullチェックのような処理がエラーになるような場合のチェックはメソッド内で行い、例外をthrowしたりすると思います。
では、状態チェックメソッドで受け取った5文字の文字列とチェックするような場合、文字列が5文字であるかどうかをメソッド側で5文字でないと例外を返す方がいいのか、単純に不一致として返すか、またはチェック処理前に文字列を5文字分切り出す処理を入れる方が便利でしょうか。
基本的にメソッド側でチェックするとして、どの程度厳密にチェックするのかというのも明確な判断ができていません。
当然、ケースバイケースということになると思いますが、
そのあたりの設計の指標を教えていただけるとありがたいです。
自分で調べた感じでは以下
・メソッドの場合、それがpublicかprivateか
publicの場合、厳密にチェック、privateの場合はエラーチェックはassertを使う?
・受け取った引数が、ユーザーからの入力値のような外部要因のものかどうか
外部の場合はバリデーション含めて、チェック
よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/02/26 11:58

回答2件
2
ベストアンサー
こんにちは。
メソッド、関数の引数チェックを呼び出し先で行うか、呼び出し元で行うかの設計で悩んでいます。
一般に関数は複数の箇所から呼ばれるでしょうから、通常は関数側でチェックした方が良いように感じます。1箇所からしか呼ばれない関数ならどちらでチェックしてもよいように思います。パラメータを増やさずにチェックとエラー報告ができるなら、関数側でチェックしておくと他の場所からも呼びたくなった時に楽できるかも知れません。
当然、ケースバイケースということになると思いますが、
そのあたりの設計の指標を教えていただけるとありがたいです。
指標として妥当かどうか分かりませんが、私は概ね以下のようなイメージで対処してます。
例外
続行不可能なエラーや本来有り得ないエラーはできるだけ例外を投げてます。バグかリソース不足が多いです。(このエラー対処用のコードの数が一番多くなると思います。)
そして、できるだけ大本でcatchしてログに残すようにしてます。C#はスタック・トレースがお手軽なのでありがたいです。C++も最近スタック・トレースが標準化されたらしいので使う機会を待っているところです。
アサート
例外を投げることができない場合はアサートすることがあります。例えばC++でデストラクタで検出した続行不能エラーで実稼働中に発生することが考えにくいケースなど。
エラーコード
操作ミスなら、オペレータに通知することになりますね。その時は、エラーコードで返却した方がオペレータに通知して対処を促しやすい場合が多いように感じます。(常に成り立つわけではないですが。)
ただし、ハードウェアの故障やハードウェアの接続ミス等も基本はオペレータに通知して対処して貰うことになりますが発生頻度は低いですし、続行不能な場合が多いですから、例外を使うことが多いですね。
投稿2018/02/26 14:00
総合スコア23274
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

1
似たような質問がありましたので、一応参考までにリンクを貼り付けておきます。
実行制限のある関数の記述方法 - Teratail
そもそも不正と分かっている値を使って、
関数やメソッドの引数に投げ込むのはお行儀が良いプログラムだとは思いません。
DBには常に既に綺麗な値が入っているべきなので基本的には信頼しても良い、見張るのはユーザーからの入力値だけで良いと思います。
それでも失敗しそうなリスクを抱えているなら(例えばSQLがエラーになる、DBやHTTP通信が失敗する等)
tryで受け取れるように準備しておくべきかなと考えています。
この前提を元に回答する形になります。
状態チェックメソッド
素直に一致しなければ全部falseで良いと思います。
次点は型が違う、null、5文字以外のケースなら即例外ですかね。
メソッドや関数はシンプル低機能なのが一番です。
高機能であればあるほど使いにくい負の遺産になると考えてください。
何故ならば、高機能になればなるほど外からは何やってんのか見えなくなります。
つまり外から中が透けて見える関数やメソッド名にする必要があります。
余り端折りすぎた名前を付けるのは、未来の自分や同僚に「ファルシのルシがパージでコクーン」を押し付ける事になります。
先頭の5文字を直訳すれば「The beginning of the 5 characters」で、既に長すぎでしょう。
これに更にチェックを行いtrue or falseを返すシンプルな名前を考えると辛いですね。
関数型プログラミングではtake 5
がString型なら先頭から5文字を抜き出すという意味で使われる事が多いです。
定義されたコード一覧に含まれるという感じでin declared code
でしょうか?
うーん、私の英語力じゃこんなもんですか、色々考えてみてください。
JavaScript
1var take = function (num, str) { 2 if (str.length === num) return str; 3 if (str.length > num) return str.slice(0, num); 4 return (Array(num).fill('0').join('') + str).slice(0 - num); 5} 6var inDeclaredCode = function (str) { 7 var codes ['00000', '00001']; 8 return (codes.indexOf(str) !== -1); 9} 10var str = "12345"; 11var result = inDeclaredCode(take(5, str));
投稿2018/02/26 12:38
総合スコア21418
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。

あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。