これの続きー。ぞくぞくしてきたぞー。
僕の好きなコードの書き方 - Mitsuyuki.Shiiba
続:僕の好きなコードの書き方 - Mitsuyuki.Shiiba
続々:僕の好きなコードの書き方 - Mitsuyuki.Shiiba
続々々:僕の好きなコードの書き方 - Mitsuyuki.Shiiba
今日はここから
最初のメソッドについて考える
public Result execute(Input in) { try { return a(in); } catch (Exception e) { LOG.error(e); return createResult(in.getCoins(), null); } }
ふむ。これinがnullのときはaメソッドの中でNPEが発生してcatchの中でさらにNPEが発生するね。これでいいんかな?どうしよう。
そもそもこのexecuteメソッドのパラメータがどういう状態で渡されてくるんだろうか・・・。とりあえず、早めにNPEにしとくか。
public Result execute(Input in) { if (in == null) { throw new NullPointerException("In is null."); } try { return a(in); } catch (Exception e) { LOG.error(e); return createResult(in.getCoins(), null); } }
ふむ。これでちょっとやりやすくなった。
aメソッドのパラメータを変えてみる
なんとなく、aメソッドをinから解放したかったので。こうしてみた。
public Result execute(Input in) { if (in == null) { throw new NullPointerException("In is null."); } try { return a(in.getSelected(), in.getCoins()); } catch (Exception e) { LOG.error(e); return createResult(in.getCoins(), null); } } Result a(Integer aSelected, List<Integer> aCoins) { if (isInvalidSelected(aSelected)) { throw new IllegalArgumentException(); } if (isInvalidCoins(aCoins)) { throw new IllegalArgumentException(); } Product product = dao.findById(aSelected); if (product == null) { return createResult(aCoins, null); } return b(aCoins, product); }
aメソッドの中で考えることが、少しだけ減って幸せ。
名前を考える
さて、ついに名前を考え始めようか。
aSelectedとaCoinsだけど、もうちょい分かりやすく。こうかな?
Result a(Integer aProductId, List<Integer> aInputCoins) { if (isInvalidSelected(aProductId)) { throw new IllegalArgumentException(); } if (isInvalidCoins(aInputCoins)) { throw new IllegalArgumentException(); } Product product = dao.findById(aProductId); if (product == null) { return createResult(aInputCoins, null); } return b(aInputCoins, product); }
isInvalidSelected
次はisInvalidSelected。
boolean isInvalidSelected(Integer selected) { return !(selected != null && selected > 0 && selected < 11); }
こうかな?
boolean isNotValidProductId(Integer aProductId) { return !isValidProductId(aProductId); } boolean isValidProductId(Integer aProductId) { if(aProductId == null) { return false; } int productId = aProductId.intValue(); return (0 < productId && productId < 11); }
冗長な気もするけど。「〜でない」ときを考えるより「〜である」ときを考える方が好きなので。
isInvalidCoins
同じ感じで。
boolean isInvalidCoins(List<Integer> coins) { return !(coins != null && coins.size() > 0 && coins.size() < 101); }
こうしてみた。
boolean isNotValidInputCoins(List<Integer> aInputCoins) { return !isValidInputCoins(aInputCoins); } boolean isValidInputCoins(List<Integer> aInputCoins) { if(aInputCoins == null) { return false; } int coinCount = aInputCoins.size(); return (coinCount > 0 && coinCount < 101); }
Productを取得する部分
この部分を見て。ちょっと悩む。
if (isNotValidProductId(aProductId)) { throw new IllegalArgumentException(); } if (isNotValidInputCoins(aInputCoins)) { throw new IllegalArgumentException(); } Product product = dao.findById(aProductId); if (product == null) { return createResult(aInputCoins, null); }
Productが見つからなかった時は、createResultしてるんだけど。
パラメータが不正な場合は例外投げてて。最終的にはどっちも同じ結果を返すのよね。。。
1) 入力値エラーの場合も、createResultする。
2) Productが見つからない場合も、例外投げる。
3) そのまま
んー。どうしよう?(2)にしようかな。gotoっぽい?いいや。
Result a(Integer aProductId, List<Integer> aInputCoins) { if (isNotValidProductId(aProductId)) { throw new IllegalArgumentException("ProductId is not valid."); } if (isNotValidInputCoins(aInputCoins)) { throw new IllegalArgumentException("InputCoins is not valid."); } Product product = dao.findById(aProductId); if (product == null) { throw new IllegalArgumentException("Product doesn't exist."); } return b(aInputCoins, product); }
bメソッドに進む前に
ちょこっと整理したい。
やっぱり、isNotValidメソッドが冗長な感じがするので、こうしてみる?
Result a(Integer aProductId, List<Integer> aInputCoins) { if (!isValidProductId(aProductId)) { throw new IllegalArgumentException("ProductId is not valid."); } if (!isValidInputCoins(aInputCoins)) { throw new IllegalArgumentException("InputCoins is not valid."); } Product product = dao.findById(aProductId); if (product == null) { throw new IllegalArgumentException("Product doesn't exist."); } return b(aInputCoins, product); }
でも僕「!」好きくないので。こういうユーティリティクラスを用意することにする。
public class Not { public static boolean not(boolean aBoolean) { return !aBoolean; } }
で、staticインポートして使う。
Result a(Integer aProductId, List<Integer> aInputCoins) { if (not(isValidProductId(aProductId))) { throw new IllegalArgumentException("ProductId is not valid."); } if (not(isValidInputCoins(aInputCoins))) { throw new IllegalArgumentException("InputCoins is not valid."); } Product product = dao.findById(aProductId); if (product == null) { throw new IllegalArgumentException("Product doesn't exist."); } return b(aInputCoins, product); }
で、guava使おうかなとか、Coinクラスを作りたいな、とか思いながら。今日はおしまい。
イマココ