とりあえず雑記帳(跡地)
じゃあ何が問題?
最終更新:
fujiyan
-
view
演算を追加してみる
先に作成したプログラムに、新しい演算「累乗」を追加してみましょう。
/*
* オブジェクト指向でない版
* 累乗を追加
*/
package jp.fujiyan.binaryoperation2;
import java.io.BufferedReader;
import java.io.EOFException;
import java.io.IOException;
import java.io.InputStreamReader;
/**
* 二項演算です。
*
* @author fujiyan
*/
public class BinaryOperation {
// 入力値の最小
private static final int MIN_VALUE = -99999;
// 入力値の最大
private static final int MAX_VALUE = 99999;
// 選択肢
private static final int FINISH = 0;
private static final int ADDITION = 1;
private static final int SUBTRACTION = 2;
private static final int MULTIPLICATION = 3;
private static final int DIVISION = 4;
private static final int POWER = 5;//$$$$$修正$$$$$
/**
* ユーザ入力を返します。
*
* @param prompt プロンプト文
* @return ユーザ入力文字列
*/
private static String input(String prompt) throws IOException {
System.out.println(prompt);
BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
String str = in.readLine();
if (str == null) {
// Ctrl+Zによる中断
throw new EOFException("中断されました。");
}
return str;
}
/**
* 整数値を問い合わせます。
*
* @return 整数値
*/
private static int askValue(int seq) throws IOException {
int value = 0;
boolean invalid = true;
while (invalid) {
// 整数値が入力されるまで
String ret = input(String.valueOf(seq) + "番目の数値を入力してください(" + MIN_VALUE + "~" + MAX_VALUE + "の整数)。");
try {
value = Integer.parseInt(ret);
} catch (NumberFormatException e) {
// 整数値として有効でない文字列
System.out.println("入力された値は整数値ではありません。");
continue;
}
invalid = (value < MIN_VALUE) || (value > MAX_VALUE);
if (invalid) {
// 無効な入力
System.out.println("入力された数値が範囲を超えています。");
}
}
return value;
}
/**
* 操作を問い合わせます。
*
* @return 操作の選択肢
*/
private static int askOperation() throws IOException {
String prompt = "操作を番号で選択してください。(" +
FINISH + ":終了 " +
ADDITION + ":加算 " +
SUBTRACTION + ":減算 " +
MULTIPLICATION + ":乗算 " +
DIVISION + ":除算 " +
POWER + ":累乗" +//$$$$$修正$$$$$
")";
int operation = 0;
boolean invalid = true;
while (invalid) {
// 有効な選択肢が入力されるまで
String ret = input(prompt);
try {
operation = Integer.parseInt(ret);
invalid = (operation < 0) || (operation > POWER);//$$$$$修正$$$$$
} catch (NumberFormatException e) {
// 数値として有効でない文字列
}
if (invalid) {
// 無効な入力
System.out.println("正しい番号を選択してください。");
}
}
return operation;
}
/**
* 演算を行います。
*
* @param operation 操作の選択肢
* @param value1 値1
* @param value2 値2
*/
private static void execute(int operation, int value1, int value2) {
String expression = null;
String result = null;
switch (operation) {
case ADDITION:
// 加算
expression = String.valueOf(value1) + " + " + String.valueOf(value2);
result = String.valueOf(value1 + value2);
break;
case SUBTRACTION:
// 減算
expression = String.valueOf(value1) + " - " + String.valueOf(value2);
result = String.valueOf(value1 - value2);
break;
case MULTIPLICATION:
// 乗算
expression = String.valueOf(value1) + " × " + String.valueOf(value2);
result = String.valueOf((long) value1 * value2);
break;
case DIVISION:
// 除算
if (value2 == 0) {
// 0除算
System.out.println("0で割ることはできません。");
return;
}
expression = String.valueOf(value1) + " ÷ " + String.valueOf(value2);
result = String.valueOf(value1 / value2) + "(余り " + String.valueOf(value1 % value2) + ")";
break;
case POWER://$$$$$修正$$$$$
// 累乗
expression = String.valueOf(value1) + " ^ " + String.valueOf(value2);
result = String.valueOf((long) Math.pow(value1, value2));
break;
}
System.out.println(expression + " の答えは " + result + " です。");
}
/**
* メインメソッドです。
*
* @param args コマンドライン引数
*/
public static void main(String[] args) {
try {
int operation = askOperation();
while (operation != FINISH) {
// "終了"が選択されるまで
int val1 = askValue(1);
int val2 = askValue(2);
execute(operation, val1, val2);
operation = askOperation();
}
System.out.println("終了します。");
} catch (EOFException e) {
// Ctrl+Zによる中断
System.err.println(e.getMessage());
} catch (Exception e) {
// その他例外
System.err.println("なんかまずいことが発生しました。");
e.printStackTrace();
}
}
}
累乗を追加するに当たり、4箇所のプログラム修正を行っています。
この「プログラム修正」に問題が出てきます。
この「プログラム修正」に問題が出てきます。
問題1、プログラム全体の解析が必要
そもそも、どこを修正すればいいか、プログラム全体を把握する必要があります。
特に、askOperation()メソッド内の、
特に、askOperation()メソッド内の、
invalid = (operation < 0) || (operation > POWER);//$$$$$修正$$$$$
の部分とか、本当に見落とします。実際、このサンプル作る際に見落としました(汗
今回みたいな単純なプログラムなら未だしも、
規模が大きくなるにつれ大変な作業になります。ましてや、自分が作ったわけではなく、他人が作ったプログラムになると…。
規模が大きくなるにつれ大変な作業になります。ましてや、自分が作ったわけではなく、他人が作ったプログラムになると…。
問題2、修正によって、動作実績のある既存の部分が動かなくなってしまう可能性がある
特にexecute()メソッドの修正ですが、既に存在する演算を実施する部分に手を加えています。
うまく修正できればイイですが、そこは人間、間違いもあります。特に、先にあげたプログラム全体の把握が出来ていないと、
問題ないと思っていた修正が、思わぬところに影響を及ぼすことも多々あります。
うまく修正できればイイですが、そこは人間、間違いもあります。特に、先にあげたプログラム全体の把握が出来ていないと、
問題ないと思っていた修正が、思わぬところに影響を及ぼすことも多々あります。
追加機能でバグがでるのはまだ許されますが、既に動いていた部分まで動かなくなるのは、
既存ユーザーからお叱りを受けます。
既存ユーザーからお叱りを受けます。