-
Notifications
You must be signed in to change notification settings - Fork 6
민형 문자열 덧셈 계산기 #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| package calculator; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| public class CalculatorService { | ||
|
|
||
| public int calculate(String expression) { | ||
| List<Number> numbers = Splitter.getSplitNumbers(expression); | ||
|
|
||
| Number result = numbers.stream() | ||
| .reduce(Number::sum) | ||
| .orElseThrow(() -> new ArithmeticException()); | ||
|
|
||
| return result.getValue(); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package calculator; | ||
|
|
||
| public class Number { | ||
| private final int value; | ||
|
|
||
| public Number(String value) { | ||
| this.value = parseString(value); | ||
| } | ||
|
|
||
| public Number(int value) { | ||
| this.value = value; | ||
| } | ||
|
|
||
| public int getValue() { | ||
| return value; | ||
| } | ||
|
|
||
| public static Number sum(Number a, Number b) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클래스 메서드보단 number.sum(number)가 더 좋은 객체관계일거같아요 |
||
| return new Number(a.getValue() + b.getValue()); | ||
| } | ||
|
|
||
| private int parseString(String value) { | ||
| validateNumber(value); | ||
| int result = Integer.parseInt(value); | ||
|
|
||
| if (result < 0) { | ||
| throw new RuntimeException(String.format("음수가 입력되었습니다. : %s ", result)); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
|
|
||
| private void validateNumber(String value) { | ||
| if (value == null || value.isEmpty()) { | ||
| throw new RuntimeException("빈 문자열 입니다."); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 RunTimeException 을 구현한 애로 쓰는게 더 좋지않낭?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 조금 헷갈리는게 요구사항엔 단순하게 RuntimeException을 던지라고 나와있어서 이렇게 했는데 조금 더 고민해보고 수정해볼께! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오호 요구사항이 그랬구나 난 바보야 |
||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| package calculator; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
| import java.util.regex.Matcher; | ||
| import java.util.regex.Pattern; | ||
| import java.util.stream.Collectors; | ||
|
|
||
| public class Splitter { | ||
| private static final String COMMON_DELIMITER = "[,:]"; | ||
| private static final Pattern CUSTOM_DELIMITER_PATTERN = Pattern.compile("//(.)\n(.*)"); | ||
| private static final String DEFAULT_NUMBER = "0"; | ||
| private static final int DELIMITER_GROUP = 1; | ||
| private static final int FORMULA_GROUP = 2; | ||
|
|
||
| public static List<Number> getSplitNumbers(String expression) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 아하 여기서 Number 로 꺼내주는방법이있었구나 .. |
||
| if (expression == null || expression.isEmpty()) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 매번 추가 DELIMITER가 추가될때마다 if문이 하나씩 추가될꺼같은데 이런 구조보단 Splitter를 인터페이스로 빼고 여러 Splitter를 구현해서 다른 방식으로 해결하는게 좋을듯 |
||
| return commonSplit(DEFAULT_NUMBER); | ||
| } | ||
|
|
||
| Matcher matcher = CUSTOM_DELIMITER_PATTERN.matcher(expression); | ||
| if (matcher.find()) { | ||
| return customSplit(matcher); | ||
| } | ||
|
|
||
| return commonSplit(expression); | ||
| } | ||
|
|
||
| private static List<Number> customSplit(Matcher matcher) { | ||
| String delimiter = matcher.group(DELIMITER_GROUP); | ||
| String formula = matcher.group(FORMULA_GROUP); | ||
| return Arrays.stream(formula.split(delimiter)) | ||
| .map(Number::new) | ||
| .collect(Collectors.toList()); | ||
| } | ||
|
|
||
| private static List<Number> commonSplit(String expression) { | ||
| return Arrays.stream(expression.split(COMMON_DELIMITER)) | ||
| .map(Number::new) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| package calculator; | ||
|
|
||
| import org.assertj.core.api.ThrowableAssert; | ||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.NullAndEmptySource; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| class CalculatorServiceTest { | ||
|
|
||
| @DisplayName("기본 구분자로 식 입력시 결과 반환") | ||
| @Test | ||
| void name() { | ||
| String expression = "1,2:3"; | ||
| CalculatorService calculatorService = new CalculatorService(); | ||
| int result = calculatorService.calculate(expression); | ||
| assertThat(result).isEqualTo(6); | ||
| } | ||
|
|
||
| @DisplayName("커스텀 구분자로 식 입력시 결과 반환") | ||
| @Test | ||
| void name1() { | ||
| String expression = "//h\n1h2h3"; | ||
| CalculatorService calculatorService = new CalculatorService(); | ||
| int result = calculatorService.calculate(expression); | ||
| assertThat(result).isEqualTo(6); | ||
| } | ||
|
|
||
| @DisplayName("1 입력시 1 반환") | ||
| @Test | ||
| void name4() { | ||
| String expression = "1"; | ||
| CalculatorService calculatorService = new CalculatorService(); | ||
| int result = calculatorService.calculate(expression); | ||
| assertThat(result).isEqualTo(1); | ||
| } | ||
|
|
||
| @DisplayName("빈 문자열, null 입력시 0") | ||
| @ParameterizedTest | ||
| @NullAndEmptySource | ||
| void name2(String expression) { | ||
| CalculatorService calculatorService = new CalculatorService(); | ||
| int result = calculatorService.calculate(expression); | ||
| assertThat(result).isEqualTo(0); | ||
| } | ||
|
|
||
| @DisplayName("음수 값 있을때 RuntimeExcetion Throw") | ||
| @Test | ||
| void name3() { | ||
| String expression = "1,-2:3"; | ||
| CalculatorService calculatorService = new CalculatorService(); | ||
| assertThatThrownBy(() -> calculatorService.calculate(expression)) | ||
| .isInstanceOf(RuntimeException.class) | ||
| .hasMessage(String.format("음수가 입력되었습니다. : %s ", -2)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package calculator; | ||
|
|
||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
| import org.junit.jupiter.params.ParameterizedTest; | ||
| import org.junit.jupiter.params.provider.CsvSource; | ||
| import org.junit.jupiter.params.provider.EmptySource; | ||
| import org.junit.jupiter.params.provider.NullAndEmptySource; | ||
| import org.junit.jupiter.params.provider.ValueSource; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThatThrownBy; | ||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| class NumberTest { | ||
| @DisplayName("빈 문자열 또는 null일시 RuntimeException Throw") | ||
| @ParameterizedTest | ||
| @NullAndEmptySource | ||
| void name1(String expression) { | ||
| assertThatThrownBy(() -> new Number(expression)) | ||
| .isInstanceOf(RuntimeException.class) | ||
| .hasMessage("빈 문자열 입니다."); | ||
| } | ||
|
|
||
| @DisplayName("음수일시 RuntimeException Throw") | ||
| @Test | ||
| void name() { | ||
| assertThatThrownBy(() -> new Number("-1")) | ||
| .isInstanceOf(RuntimeException.class) | ||
| .hasMessage(String.format("음수가 입력되었습니다. : %s ", -1)); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package calculator; | ||
|
|
||
| import jdk.nashorn.internal.ir.annotations.Ignore; | ||
| import org.junit.jupiter.api.DisplayName; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| class SplitterTest { | ||
|
|
||
| @DisplayName("일반적인 식 입력시 분리된 숫자 List가 반환") | ||
| @Test | ||
| void name() { | ||
| String expression = "1,2:3,4"; | ||
| List<Number> numbers = Splitter.getSplitNumbers(expression); | ||
| assertThat(numbers.size()).isEqualTo(4); | ||
| } | ||
|
|
||
| @DisplayName("커스텀 구분자로 입력시 분리된 숫자 List가 반환") | ||
| @Test | ||
| void name1() { | ||
| String expression = "///\n1/2/3/6"; | ||
| List<Number> numbers = Splitter.getSplitNumbers(expression); | ||
| assertThat(numbers.size()).isEqualTo(4); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stream 구문 이후 그 결과값을 받은뒤 return 하는거보다
return 에서 stream 구문을 끝내도록 하는게 좀 더 가독성이 좋을거같습니다. 아직 익숙하지 않아서 적절한 예시를 알려주진 못하지만 ..ㅠㅠ
찬인이형이 잘 했놧다고 생각합니당
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
그냥 Number객체를 리턴하는게 좋아보이네요