プロセス指向
要件:Javaを使用して、結果を取得するために2つの数値と演算子を入力する必要がある計算機コンソールプログラムを実装します。
1)簡単な実装
public static void version1() {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字A:");
int A = scanner.nextInt();
System.out.println("请输入数字B:");
int B = scanner.nextInt();
System.out.println("请输入运算符号(+、-、*、/):");
String oper = scanner.next();
int result = 0;
if (oper.equals("+")) {
// 问题1:分支判断写法不好,计算机做了3次无用功
result = A + B;
}
if (oper.equals("-")) {
result = A - B;
}
if (oper.equals("*")) {
result = A * B;
}
if (oper.equals("/")) {
result = A / B; // 问题2:如果除数时输入0如何处理,输入的是字符符号不是数字如何处理
}
System.out.println("结果是:" + result);
}
既存の問題:
- ブランチジャッジメントの記述は良くないので、コンピュータは3回の無駄な作業をします。
- 除算時に0を入力するとどうなりますか?入力が数字ではなく文字記号の場合はどうすればよいですか?
2)改善
- スイッチによるブランチ変換
- 除数の判断を追加し、try...catchを追加しました
public static void version2() {
try {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字A:");
int A = scanner.nextInt();
System.out.println("请输入数字B:");
int B = scanner.nextInt();
System.out.println("请输入运算符号(+、-、*、/):");
String oper = scanner.next();
int result = 0;
switch (oper) {
case "+":
result = A + B;
break;
case "-":
result = A - B;
break;
case "*":
result = A * B;
break;
case "/":
if (B != 0) {
result = A / B;
} else {
throw new IllegalArgumentException("除数不能为0");
}
break;
}
System.out.println("结果是:" + result);
} catch (Exception e) {
System.out.println("您的输入有误:" + e.getMessage());
}
}
以上は機能を実現するためだけのものですが、実はコンピューターのように考えています。たとえば、プログラムは2つの数字と演算子記号の入力を必要とし、次に演算子記号に従って操作方法を選択し、それ自体が間違っていない結果を取得します。しかし、このような考え方では、私たちのプログラムは現在のニーズを満たすだけであり、プログラムは[維持]、[拡張]、さらには[再利用]が難しく、高品質を満たせません。要件。
オブジェクト指向
要件:別のWindows計算機を作成する必要がありますが、上記のコードを再利用できますか?
1)簡単な実装
コードに一定レベルの反復コードが含まれている場合、メンテナンスは大惨事になる可能性があります。システムが大きくなればなるほど、問題は深刻になります。プログラミングには原則があり、繰り返しをできるだけ避け、計算機に関連するものとコンソールに関連しないものを検討します。ビジネスロジックをインターフェイスロジックから分離し、それらの間の結合を減らします。
/**
* 运算类(Operation):
* 在Windows程序、Web版程序、PDA、手机等需要移动系统的软件需要运算都可以用它。
*/
public class Operation {
public static double getResult(double A, double B, String operate) {
double result = 0d;
switch (operate) {
case "+":
result = A + B;
break;
case "-":
result = A - B;
break;
case "*":
result = A * B;
break;
case "/":
result = A / B;
break;
}
return result;
}
}
クライアントコード:
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数字A:");
int A = scanner.nextInt();
System.out.println("请输入数字B:");
int B = scanner.nextInt();
System.out.println("请输入运算符号(+、-、*、/):");
String oper = scanner.next();
double result = Operation.getResult(A, B, oper);
System.out.println("结果是:"+result);
}
2)改善
Q:ルート操作を追加したい場合、どうすれば変更できますか?
回答:操作クラスを変更するだけで、スイッチにブランチを追加するだけです。
問題は、平方根演算を追加する場合、コンパイルに含まれる加算、減算、乗算、除算の演算を行う必要があることです。誤って減算への加算を変更した場合でも、悪くはありません。元々は関数を追加できましたが、うまく実行される関数コードを変更すると、リスクが大きすぎます。したがって、加算、減算、乗算、除算などの演算は分離する必要があります。これらを変更しても他の演算には影響せず、演算アルゴリズムを追加しても他のコードには影響しません。
public abstract class Operation {
private double numberA = 0;
private double numberB = 0;
/**
* 子类实现运算操作
*/
public abstract double getResult();
public double getNumberA() {
return numberA;
}
public void setNumberA(double numberA) {
this.numberA = numberA;
}
public double getNumberB() {
return numberB;
}
public void setNumberB(double numberB) {
this.numberB = numberB;
}
}
// 加
public class OperationAdd extends Operation {
@Override
public double getResult() {
return getNumberA() + getNumberB();
}
}
// 减
public class OperationSub extends Operation {
@Override
public double getResult() {
return getNumberA() - getNumberB();
}
}
// 乘
public class OperationMul extends Operation {
@Override
public double getResult() {
return getNumberA() * getNumberB();
}
}
// 除
public class OperationDiv extends Operation {
@Override
public double getResult() {
if (getNumberB() == 0) {
throw new IllegalArgumentException("除数不能为0");
}
return getNumberA() / getNumberB();
}
}
3)単純なファクトリパターン
使用するアルゴリズムを電卓に知らせるにはどうすればよいですか?単純なファクトリパターンを使用します。
誰がインスタンス化されますか?ルート原因操作の追加など、将来インスタンス化されるオブジェクトは増えます
か?これは簡単に変更できる場所です。インスタンスの作成プロセスには別のクラスを使用することを検討する必要があります。工場。
public class OperationFactory {
public static Operation createOperate(String operate) {
Operation oper = null;
switch (operate) {
case "+":
oper = new OperationAdd();
break;
case "-":
oper = new OperationSub();
break;
case "*":
oper = new OperationMul();
break;
case "/":
oper = new OperationDiv();
break;
}
return oper;
}
}
クライアントクラス:
操作シンボルを入力するだけで、ファクトリは適切なオブジェクトをインスタンス化し、ポリモーフィズムを介して親クラスを返すことで計算機の結果を実現します。
変更する場合:1:操作サブクラスを追加します2:Inファクトリクラスはスイッチブランチを追加します
public static void main(String[] args) {
Operation oper= OperationFactory.createOperate("+");
oper.setNumberA(1);
oper.setNumberB(2);
double result = oper.getResult();
System.out.println(result);
}