こんにちは。新卒1年目エンジニアのrs_shoです。
投稿は3回目になります。
今回は実装の際に気を付けるべき汎用メソッドの落とし穴についてお話ししたいと思います。
はじめに
皆さん、javaでコーディングする時によく使うUtilsの便利なメソッド、コーディングが楽ですよね。
実装する際によくStringUtilsやNumberUtilsなど、色々な汎用メソッドを多用して
楽にコーディングできるので、ついつい使ってしまいがち。。。
そういう僕も良く汎用メソッドを使って実装することが多々ありますが、今回はそのメソッドを使った際に
困ってしまったお話をしようと思います。
そもそも何に困ったのか
僕は今回org.apache.commons.lang.math.NumberUtils
のisNumber
を使用して、数値の判定をする部分のコーディングをしていました。
入力された値が数値なのかを判定してくれるメソッドです。
実装していて、実装後のテスト時にあれ?変だな。。。と思いました。
NumberUtils.isNumber()
は普通の数値以外に
- 8進数
- 16進数
- 指数表記(科学的表記法)
- 型修飾子のついた数値
など、通常の数値(10進数)として扱うには、変換が必要な数値まで通してしまうのです。(2進数は文字列判定らしいです)
これでは計算などをするためにキャストしたりする時にNumberFormatException
などが出て困りますね。。。
解決するためにどういう案があるのか
この問題を解決するためには、いくつか案はありましたが、どれが一番正しいのか、かなり迷ってしまいました。
僕の主観でですが、考えた案をメリット・デメリットを含めてお伝えしたいと思います。
* 変換をして変換できなかったらエラーを出す(try-catch文) * メリット * 必要な数値だけ選んで取れるほか、エラーのカスタマイズが容易(数値の型指定やエラーをcatchの中で設定できる) * デメリット * エラーを握りつぶすことになる(実装ではなるべくしない方が望ましい。。。) * try-catch文はパフォーマンスが落ちる(調べた範囲でですが、色々なクラスに遷移するので遅い) * 自分でメソッドを作ってしまう * メリット * 自分で書くので、必要な処理だけ書ける * デメリット * 開発コストがかなりかかる(汎用メソッドを補うため、考慮すべき点が多すぎる) * 考慮漏れがある可能性大(自分でコードを書くため、考慮漏れが発生しやすい) * 正規表現で数値かどうかを判定する * メリット * 正規表現が扱えれば自由度が高い * デメリット * (あくまで主観ですが)可読性が悪い、コードが汚く見える * 判定する文字列が長ければ長いほどパフォーマンスが落ちる
色々調べた結果、どの実装にもメリット・デメリットがあり、実装の内容によりけりって感じですね。。。
ちなみに僕はtry-catchと正規表現を使用しました。
考慮漏れを防ぐためにも、ある程度組み合わせたほうが安全だと思います。
おわりに
いかがでしたか。僕はこの問題に直面してからコーディングにものすごく時間を使いました。
みなさんのコーディングの助けになれば幸いです。