Conversation
refactor: delete unused class and fix naming
| case '/': | ||
| result = tempResult / operand; | ||
| break; |
| @Test | ||
| void 사칙연산() { | ||
| double addition, subtraction, multiplication, division, wrongOperatorResult; | ||
|
|
||
| addition = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(0), operands.get(1)); | ||
| subtraction = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(1), | ||
| operands.get(1)); | ||
| multiplication = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(2), | ||
| operands.get(1)); | ||
| division = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(3), operands.get(1)); | ||
| wrongOperatorResult = calculator.fourFundamentalArithmeticOperations(operands.get(0), '?', operands.get(1)); | ||
|
|
||
| assertThat(addition).isEqualTo(6.0); | ||
| assertThat(subtraction).isEqualTo(-2.0); | ||
| assertThat(multiplication).isEqualTo(8.0); | ||
| assertThat(division).isEqualTo(0.5); | ||
| assertThat(wrongOperatorResult).isEqualTo(0); | ||
| } |
There was a problem hiding this comment.
더하기, 빼기, 곱하기, 나누기 등 기능 별로 따로 테스트를 만드는 건 어떨까요!!
예를 들어 이 테스트에서 뺄셈에서만 작동하지 않을 경우에도 이 테스트 전체에서 작동하지 않는다고 나올거 같아서요!
There was a problem hiding this comment.
동의합니다!
단위 테스트이기 때문에 최대한 작은 단위를 테스트 해주시는것이 좋아요.
또한 테스트도 유지보수의 대상이기 때문에 작게 유지할 수록 좋답니다.
begaonnuri
left a comment
There was a problem hiding this comment.
잘 구현해 주셨네요! 👍🏻
몇가지 변경사항 남겨놨으니 반영해주세요!
| ### 기능 | ||
| - 예외 | ||
| - [x] 숫자로 시작하지 않을 경우 | ||
| - [x] 띄어쓰기가 잘 안 돼서 숫자와 문자가 섞였을 경우(공백문자 미사용) | ||
| - [x] 숫자와 연산자 이외의 문자 | ||
| - [x] 연산자나 숫자가 두 번 이상 연속으로 나올 경우 | ||
| - 순서 | ||
| - [x] 문자열 입력 받기 | ||
| - [x] 띄어쓰기로 분리해서 배열에 넣기 | ||
| - [x] 예외 처리 | ||
| - [x] 피연산자(operand 숫자)와 연산자(operator +-/*)로 나누기 | ||
| - [x] 계산하기 |
| Scanner scanner = new Scanner(System.in); | ||
| String input = scanner.nextLine(); |
There was a problem hiding this comment.
비즈니스 로직과 뷰 로직의 분리 👍🏻
근데 애플리케이션이 너무 불친절한것같아요!
안내메시지 없이 밑도끝도 없이 숫자를 입력하라그러네요 😂
| Scanner scanner = new Scanner(System.in); | ||
| String input = scanner.nextLine(); |
There was a problem hiding this comment.
Application의 역할은 무엇일까요?
그리고 입력해야 하는 메소드와 출력해야 하는 메소드가 많아질 경우 어떻게 해야할까요?
| public Operation(String input) { | ||
| this.operation = input.split(" "); | ||
| validateOperation(); | ||
| splitOperation(); | ||
| } |
There was a problem hiding this comment.
Operation�의 역할이 너무 많은것같아요.
Operation이 지금 어떤 행위들을 하고있나요?
SRP에 대해 학습해보세요.
| import java.util.stream.Stream; | ||
|
|
||
| public class Operation { | ||
| private final String[] operation; |
There was a problem hiding this comment.
쪼갠 스트링 배열을 굳이 상태(필드)로 갖고 있을 필요가 있을까요?
클래스의 필드가 많아지면 무엇이 단점일까요?
| if ((!operation[i].matches("[+*/-]") && !operation[i + 1].matches("[+*/-]")) | ||
| || (operation[i].matches("[+*/-]") && operation[i + 1].matches("[+*/-]"))) { |
There was a problem hiding this comment.
처음 투입한 프로젝트에서 이 부분만 보고 무엇을 의미하는지 알 수 있을까요?
boolean을 리턴하는 메소드로 분리하는건 어떨까요?
| operands = Arrays.stream(this.operation) | ||
| .filter(operand -> operand.matches("^[0-9]*$") || operand.matches("^\\-[1-9]\\d*$")) | ||
| .map(Integer::parseInt) | ||
| .collect(Collectors.toList()); | ||
|
|
||
| operators = Arrays.stream(this.operation) | ||
| .filter(operator -> operator.matches("[+*/-]")) | ||
| .map(operator -> operator.charAt(0)) | ||
| .collect(Collectors.toList()); |
There was a problem hiding this comment.
Operation에서 operands와 operators를 모두 처리하려다 보니 Operation의 책임도 커지고 로직도 길어지는 경향이 생기는 것 같아요.
일급 컬렉션을 사용해 보는건 어떨까요?
이 부분은 너무 어렵게 느껴지시면 반영 안하셔도 됩니다.
| switch (operator) { | ||
| case '+': | ||
| result = tempResult + operand; | ||
| break; | ||
| case '-': | ||
| result = tempResult - operand; | ||
| break; | ||
| case '*': | ||
| result = tempResult * operand; | ||
| break; | ||
| case '/': | ||
| result = tempResult / operand; | ||
| break; | ||
| default: | ||
| result = 0; | ||
| break; |
There was a problem hiding this comment.
계산기에서 지원하는 연산자가 증가할때마다 이 switch문이 비례해서 증가할 것 같아요.
어떻게 하면 이것을 해결할 수 있을까요?
인터페이스와 다형성을 학습해보세요.
| @Test | ||
| void 사칙연산() { | ||
| double addition, subtraction, multiplication, division, wrongOperatorResult; | ||
|
|
||
| addition = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(0), operands.get(1)); | ||
| subtraction = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(1), | ||
| operands.get(1)); | ||
| multiplication = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(2), | ||
| operands.get(1)); | ||
| division = calculator.fourFundamentalArithmeticOperations(operands.get(0), operators.get(3), operands.get(1)); | ||
| wrongOperatorResult = calculator.fourFundamentalArithmeticOperations(operands.get(0), '?', operands.get(1)); | ||
|
|
||
| assertThat(addition).isEqualTo(6.0); | ||
| assertThat(subtraction).isEqualTo(-2.0); | ||
| assertThat(multiplication).isEqualTo(8.0); | ||
| assertThat(division).isEqualTo(0.5); | ||
| assertThat(wrongOperatorResult).isEqualTo(0); | ||
| } |
There was a problem hiding this comment.
동의합니다!
단위 테스트이기 때문에 최대한 작은 단위를 테스트 해주시는것이 좋아요.
또한 테스트도 유지보수의 대상이기 때문에 작게 유지할 수록 좋답니다.
| assertThatThrownBy(() -> operation = new Operation(wrongInput)) | ||
| .isInstanceOf(IllegalArgumentException.class) | ||
| .hasMessageContaining("한 String에 숫자와 연산자가 함께 있거나, "); |
There was a problem hiding this comment.
assertJ의 다양한 메소드를 잘 활용해주셨네요!
현재 모든 예외를 IllegalArgumentException으로 처리하고있어서, 메시지를 통해 확인한 점도 좋습니다 👍🏻
No description provided.