2017-03-08 3 views
0

저는 자바 프로그래밍에 익숙하지 않고 방금 계산기 프로그램을 만들었지 만 다른 프로그래머는 계산기 프로그램에서 "많은 구문 분석"을 사용하는 것으로 보입니다. 내가 잘못된 접근법을 취하고 있는지, 그리고 이런 종류의 논리를 사용하여 미래에 문제가 발생할지를 묻고 싶었습니다. 감사합니다.코드 자바 효율성에 대한 조언이 필요합니다.

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 학습의 단계로 적합하지만 프로덕션 프로그램으로 사용하지는 않을 것입니다. 이유는 코드가 명령 행 인터페이스 (static void main(), Scanner, System.out.println())를 가정하기 때문입니다.

사용자는 요즘 그래픽 솔루션에 익숙합니다. 그들은 그래픽 프론트 엔드에서 입출력이 제공 될 것으로 기대하며 계산은 별도의 로직으로 수행되어야합니다.

이보기에서

, 나는 3 개 부분으로 프로그램을 재구성합니다 :

  • 라는 계산 (다음 샘플 코드에서 계산기 클래스)
  • 프런트 엔드 클래스를 수행하는 백 엔드 클래스 (아래 SimpleFrontEnd) 코드에 빌드하지만 나중에 예 :
  • 데이터 객체가 백 엔드와 프론트 엔드 사이에서 통신 할 수있는 웹 인터페이스는이 세 부분을 갖는

(아래 계산 클래스는 프론트 엔드에서 백 엔드에 정보를 보낼 수), 당신은 독립적으로 수정할 수 있습니다 서로. 프런트 엔드에서 단일 문자열 만 입력하면 백엔드로 전송되기 전에 구문 분석됩니다.

구문 분석해야 할 프런트 엔드에서 단일 String을 사용하지는 않지만 아래 이유에서 프런트 엔드가 쉽게 피연산자와 연산자를 수정할 수있는 JSON 개체를 아래 Calculation 클래스에 직접 매핑합니다. 구문 분석해야하는 문자열을 수정하는 것은 더 복잡합니다. 여기

는 백 엔드에서 프론트 엔드 분리 샘플 코드입니다 : 나는 내가 "분석"방법을에서 많이 볼 것을 의미

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 년 전 소프트웨어 엔지니어로서 경력을 쌓았을 때 소프트웨어에 "느슨한 커플 링 및 높은 응집력"이 있어야한다는 조언을 받았습니다. 나는 그것이 소프트웨어 디자인에서 가장 중요한 단일 법이라고 생각한다. 경험을 쌓는 데있어 가장 중요한 두 가지 방법은 연습과 읽기입니다. 실제로, 당신은 다른 사람들이하고있는 것을보고 똑똑한 사람들로부터 독서를 통해 배웁니다. 행운을 빕니다! – toongeorges

0

구문 분석은 문자 그룹을 스캔 한 후 자신의 구조 (을 토큰 화)로 분리하는 것을 의미합니다.

String aStr = "10";

가변 aStrString 될 것이다. 그런 다음 문자열을 구문 분석 할 수 있습니다. 그냥 정보

int aInt = Integer.parseInt(aStr);

+0

고맙습니다. 그래서 위의 코드에서 정말 필요하지 않습니까? –

+0

문자열 대신 double을 반환하는'type.nextDouble()'을 호출하기 때문에 괜찮습니다. – PeskyPotato

0

는, 자바는 계산기 라이브러리에 구축했다.

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이 나옵니다.

그러나 그 다음에 계속 그 문자열은 \n이고 다음 문자열 입력은 문자열 \n이 할당됩니다.

구문 분석을하면이 문제가 무시됩니다. 그리고 사용자 입력을보다 잘 제어 할 수 있습니다.

+1

Smit에 대답 할 시간을내어 주셔서 감사합니다. 지금 받으시는 중입니다. –

+0

감사드립니다. 도와 줄 수있어서 기뻐. :) @ OfentseProsperNglazi – Smit

+0

당신이 "파싱"을 다른 방식으로 이해했던 것 같습니다. 스캐너와 관련이 있다면 답변이 적절합니다. – toongeorges