2017-03-08 8 views
0

私はJavaプログラミングの初心者です。電卓プログラムを作成しましたが、うまくいくと思われますが、他のプログラマーは電卓プログラムで「多くの構文解析」を使用するようです。私は間違ったアプローチをとっているのか、この種のロジックを使って将来的に問題に遭遇するのかと尋ねたがっています。コードjavaの効率に関する助言が必要です

class Refresh { 

private final String a; 
private final String b; 
private final String c; 
private final String d; 
private double x, y; 

public Refresh() { 
    a = "Enter the first number: "; 
    b = "Enter the function; "; 
    c = "Enter the second number: "; 
    d = "The result is: "; 
} 

public void types() { 
    Scanner typ = new Scanner(System.in); 

    try { 
     System.out.println(a); 
     x = typ.nextDouble(); 
    } catch (InputMismatchException e) { 
     System.out.println("Please use only numbers!"); 
     System.exit(1); 
    } 
    System.out.println(b); 
    String func = typ.next(); 

    try { 
     System.out.println(c); 
     y = typ.nextDouble(); 
    } catch (InputMismatchException e) { 
     System.out.println("Please use only numbers!"); 
     System.exit(1); 
    } 

    switch (func) { 

     case "+": 
      System.out.println(d + (x + y)); 
      break; 

     case "-": 
      System.out.println(d + (x - y)); 
      break; 
     case "/": 
      if (y == 0) { 

       System.out.println("Cannot divide by zero!"); 
      } else { 
       System.out.println(d + (x/y)); 
      } 
      break; 
     case "*": 
      System.out.println(d + (x * y)); 
      break; 

     default: 
      System.out.println(func + " is not valid function"); 
    } 
} 

    public static void main(String[] args) { 
     Refresh fin = new Refresh(); 
     fin.types(); 
    } 
} 
+1

「多くのことを解析すると、」この質問 –

+0

申し訳ありませんが、私は自分の中で「パース」の方法をたくさん見る意味では何を意味するかを説明してくださいプログラム –

答えて

0

あなたのプログラムは、デモやJavaの学習のステップとしては問題ありませんが、プロダクションプログラムとしては使用しない方がいいでしょう。その理由は、コードがコマンドラインインターフェイス(静的void main()、Scanner、System.out.println())を想定しているからです。

ユーザーは現在、グラフィカルなソリューションに慣れています。彼らは、入力と出力がグラフィカルなフロントエンドで行われることを期待しており、計算は別のロジックで行う必要があります。

このビューで

、私は3つの部分にあなたのプログラムを再構築します:

  • と呼ばれる計算(次のサンプルコードでのCalculatorクラス)
  • フロントエンドクラスを行うバックエンドクラス(以下のSimpleFrontEndを参照してください)。これはあなたのコードに基づいていますが、後に例えば
  • データオブジェクトは、バックエンドとフロントエンドの間で通信するためのWebインターフェイスは、これらの3つの部分を持つ

(以下計算クラスは、フロントエンドからバックエンドに情報を送信するために)、あなたは独立のそれらを変更することができますお互い。フロントエンドでは単一のStringのみを入力し、バックエンドに送信する前に解析することができます。

私はおそらく、解析される必要のあるフロントエンドの文字列を使用するのではなく、以下の理由から、計算クラスに直接マップするJSONオブジェクトを使用します。フロントエンドは簡単にオペランドと演算子を変更できますJSONオブジェクトのそれぞれを独立して処理する一方、解析する必要がある文字列を変更することはより複雑です。ここで

は、バックエンドからフロントエンドを分離するサンプルコードです:

public class Calculation { 
    private double leftOperand; 
    private String operator; 
    private double rightOperand; 

    public double getLeftOperand() { 
     return leftOperand; 
    } 

    public void setLeftOperand(double leftOperand) { 
     this.leftOperand = leftOperand; 
    } 

    public String getOperator() { 
     return operator; 
    } 

    public void setOperator(String operator) { 
     this.operator = operator; 
    } 

    public double getRightOperand() { 
     return rightOperand; 
    } 

    public void setRightOperand(double rightOperand) { 
     this.rightOperand = rightOperand; 
    } 
} 

public class Calculator { 
    public double calculate(Calculation calculation) { 
     switch (calculation.getOperator()) { 
      case "+": 
       return calculation.getLeftOperand() + calculation.getRightOperand(); 
      case "-": 
       return calculation.getLeftOperand() - calculation.getRightOperand(); 
      case "/": 
       if (calculation.getRightOperand() == 0) { 
        throw new IllegalArgumentException("Cannot divide by zero!"); 
       } 
       return calculation.getLeftOperand()/calculation.getRightOperand(); 
      case "*": 
       return calculation.getLeftOperand() * calculation.getRightOperand(); 
      default: 
       throw new IllegalArgumentException(String.format("%s is not valid function", calculation.getOperator())); 
     } 
    } 
} 

public class SimpleFrontEnd { 
    public static void main(String[] args) { 
     try { 
      //1. input, could be later replaced with a front end 
      Scanner typ = new Scanner(System.in); 
      System.out.println("Enter the first number: "); 
      double x = typ.nextDouble(); 
      System.out.println("Enter the function: "); 
      String func = typ.next(); 
      System.out.println("Enter the second number: "); 
      double y = typ.nextDouble(); 

      //2. store input in an data object that will be sent to the back end (later on, a web interface could send this as a JSON) 
      Calculation calculation = new Calculation(); 
      calculation.setLeftOperand(x); 
      calculation.setOperator(func); 
      calculation.setRightOperand(y); 

      //3. retrieve the result from the back end 
      Calculator calculator = new Calculator(); 
      try { 
       double result = calculator.calculate(calculation); 
       System.out.println(String.format("The result is: %f", result)); 
      } catch (IllegalArgumentException e) { 
       System.out.println(e.getMessage()); 
      } 
     } catch (InputMismatchException e) { 
      System.out.println("Please use only numbers!"); 
     } 
    } 
} 
+0

くそー!私はこれを永遠に尊重します。私はこれから多くを学ぶことができ、次の日にこのコードを勉強するだけです。どうもありがとうございます! –

+0

私が助けることができれば嬉しいことですが、これは簡単な例ですが、私の経験から最も重要なものを教えてもらえます。私は約10年前にソフトウェアエンジニアとしてキャリアをスタートしたとき、ソフトウェアには「疎結合と高い結合力」が必要であるとのアドバイスを受けました。私はこれがソフトウェア設計における最も重要な法律の一つだと思う。経験を得るためには、私は2つの最も重要な方法が練習と読書であると思います。実際には、他の人が何をしているのかを知ることができます。がんばろう! – toongeorges

0

解析だけで文字のグループをスキャンし、(それらをトークン化)、独自の構造にそれらを分離することを意味します。

String aStr = "10";

変数aStrStringであろう。その後、文字列を解析できます。

int aInt = Integer.parseInt(aStr);

+0

ありがとう、私は本当に右の上のコードでそれを必要としないのですか? –

+0

文字列の代わりにdoubleを返す 'type.nextDouble()'を呼び出すので問題ありません。 – PeskyPotato

0

ちょうどあなたの情報のために、Javaは計算ライブラリが組み込まれています。

ScriptEngineManager scriptEngineManager = new ScriptEngineManager(); 
ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("JavaScript"); 
String result = "100/10"; 
System.out.println(scriptEngine.eval(result)); 
+1

実際には、決して知りませんでした。情報のおかげで –

+0

ちょうど質問に答えてから提案をいただければ幸いです。私はこの答えがOPの質問に近いところではないと感じているからです。 Javaに慣れていないので、新しいアイテムを導入するのは圧倒的です。 – Smit

0

これは実際には非常に基本的な例です。正直なところ、あなたは素晴らしい仕事をしました。現時点でこの質問をするのがさらに優れています。通常、人々は学習プロセス中に効率を無視し、遅すぎる。

なぜ解析しますか?

あなたが以下を知っていない場合は、おそらくreadingを試してください。

スキャナは、ユーザーからのすべてのキー入力を読み取ります。

は数>12

スキャナは今12\n

あなたがそれを見開催入力例みましょうか?スキャナは実際に文字列を保持しているだけの番号を保持しています。 12\n

あなたが12と尋ねるとき、スキャナnextDoubleを聞いてください。

しかし、まだそれは\nに保持されているので、次の文字列入力は、文字列\nが割り当てられます。

解析することで、この問題は無視されます。そして、あなたはユーザー入力をより良くコントロールすることができます。

+1

スミットに答える時間をとってくれてありがとう、今、それを得ている –

+0

感謝のためにありがとう。お力になれて、嬉しいです。 :) @OfentseProsperNglazi – Smit

+0

あなたは "パース"を違った方法で理解したようです。それがスキャナに関連している場合、あなたの答えは関連しています。 – toongeorges

関連する問題