Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@osamutake
Last active August 29, 2015 14:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save osamutake/eef52076810a996831c6 to your computer and use it in GitHub Desktop.
Save osamutake/eef52076810a996831c6 to your computer and use it in GitHub Desktop.
http://bufferings.hatenablog.com/entry/2015/05/06/000943 で紹介されていた「手続き型で典型的」かつ、かなりアレなコードを自分なりにリファクタリングしてみました。
public Result execute(Input in) {
try {
Integer productId = in.getSelected();
List<Integer> coinsInserted = in.getCoins();
checkInput(productId, coinsInserted);
List<Integer> coinsRefused = new ArrayList<>();
int deposit = calcDeposit(coinsInserted, coinsRefused);
Product product = dao.findById(productId);
if (!IsProductAvailable(product, deposit)) {
return createResultWitoutProduct(coinsInserted);
}
deposit -= product.getPrice();
List<Integer> coinsForChange = calcChange(deposit);
List<Integer> coinsToReturn = ListUtils.union(coinsRefused, coinsForChange);
Result result = new Result();
result.setProduct(product);
result.setCoins(coinsToReturn);
return result;
} catch (Exception e) {
LOG.error(e);
List<Integer> coinsInserted = in.getCoins();
return createResultWitoutProduct(coinsInserted);
}
}
boolean isProductIdInRange(Integer productId, int from, int to)
{
return productId != null && from <= productId && productId <= to;
}
boolean isCoinCountInRange(List<Integer> coins, int from, int to)
{
return coins != null && from <= coins.size() && coins.size() <= to;
}
Result createResultWitoutProduct(List<Integer> coins)
{
result = new Result();
result.setCoins(coins);
result.setProduct(null);
return result;
}
// TODO: 本来なら定数を用意すべき
List<Integer> getValidCoinsDescending()
{
List<Integer> list = new ArrayList<>();
list.add(500);
list.add(100);
list.add(50);
list.add(10);
return list;
}
int calcDeposit(List<Integer> coins, List<Integer> coinsRefused)
{
int deposit = 0;
List<Integer> validCoins = getValidCoinsDescending();
for (Integer coin : coins) {
if (validCoins.contains(coin)) {
deposit += coin;
} else {
coinsRefused.add(coin);
}
}
return deposit;
}
List<Integer> calcChange(int deposit)
{
List<Integer> change = new ArrayList<>();
for (Integer coin : getValidCoinsDescending()) {
while (deposit > coin) {
change.add(coin);
}
return change;
}
// if (deposit != 0) {
// // product.Price() が 10 で割り切れない!
// throw new IllegalArgumentException("product with illegal price found");
// }
}
boolean isProductAvailable(Product product, int deposit)
{
return product != null && product.getPrice() <= deposit;
}
void checkInput(int productId, List<Integer> coinsInserted)
{
if ( !isProductIdInRange(productId, 1, 10) ) {
throw new IllegalArgumentException("productId out of range");
}
if ( !isCoinCountInRange(coinsInserted, 1, 100) ) {
throw new IllegalArgumentException("coin count out of range");
}
}
@osamutake
Copy link
Author

編集履歴についてのコメントは http://dora.bk.tsukuba.ac.jp/~takeuchi/?プログラミング%2F作法%2FHello.java にあります。

Mitsuyuki.Shiiba さんのオリジナルのコードが Gist 上に https://gist.github.com/bufferings/9414995751687177e882 としてあるのですが、特定のリビジョンから Fork する方法が解らず、コピペで新しい Gist を作ることになってしまいました。たぶん間違った方法なんだと思うのですが、どうもすみません。

ここからも解るように、私は Gist も、実は Java もあまりよく分かっていません。普段は Ruby とか JavaScript とか C# とか良く書いてます。Java のコンパイル環境もないので、タイプミスについてもご容赦下さい。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment