From da7800f2904b365008f696a519bdf4f718989d28 Mon Sep 17 00:00:00 2001 From: moongua404 Date: Sun, 2 Feb 2025 13:37:04 +0900 Subject: [PATCH 1/8] =?UTF-8?q?docs(README):=20=EB=A6=AC=EB=93=9C=EB=AF=B8?= =?UTF-8?q?=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 과제 내용 첨부 - 비지니스 로직 및 기능 목록 정리 - 구현하며 UML / Class Diagram 작성해도 좋을 것 같음 --- README.md | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bd90ef0..71a20c9 100644 --- a/README.md +++ b/README.md @@ -1 +1,46 @@ -# java-calculator-precourse \ No newline at end of file +# java-calculator-precourse + +다시 시작하는 우테코 프리코스의 꿈...이랄까..... + +
+ 과제 세부 내용 + +## 과제 + +입력한 문자열에서 숫자를 추출하여 더하는 계산기를 구현한다. + +- 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환한다. + - 예: "" => 0, "1,2" => 3, "1,2,3" => 6, "1,2:3" => 6 +- 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 "//"와 "\n" 사이에 위치하는 문자를 커스텀 구분자로 사용한다. + - 예를 들어 "//;\n1;2;3"과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다. +- 사용자가 잘못된 값을 입력할 경우 `IllegalArgumentException`을 발생시킨 후 애플리케이션은 종료되어야 한다. + +### 입출력 + +- 입력 + - 구분자와 양수로 구성된 문자열 +- 출력 + - 덧셈 결과 + +ex) + +``` +덧셈할 문자열을 입력해 주세요. +1,2:3 +결과 : 6 +``` + +
+ +## Business Logic + +- 입력을 받는다 +- 구분자가 있을 경우 추출한다 +- 모두 더한다 + +## 구현할 기능 목록 + +- [ ] 입출력 +- [ ] 구분자 추출 +- [ ] 수식 구성 +- [ ] 수식 계산 From e20b19c05065ba71970b843c1d1d33f8cf9f0584 Mon Sep 17 00:00:00 2001 From: moongua404 Date: Sun, 2 Feb 2025 13:53:30 +0900 Subject: [PATCH 2/8] =?UTF-8?q?feat(directory):=20MVC=20=ED=8C=8C=EC=9D=BC?= =?UTF-8?q?=20=EA=B5=AC=EC=A1=B0=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - MVC 패턴에 맞게 파일 구조를 설정 - model, view, controller, service, utils 패키지 및 클래스 생성 - service는 interface와 구현체로 분리 --- .../controller/CalculatorController.java | 26 +++++++++++++++++++ .../java/calculator/model/Expression.java | 5 ++++ .../calculator/service/CalculatorService.java | 4 +++ .../service/CalculatorServiceImpl.java | 5 ++++ src/main/java/calculator/view/InputView.java | 5 ++++ src/main/java/calculator/view/OutputView.java | 4 +++ 6 files changed, 49 insertions(+) create mode 100644 src/main/java/calculator/controller/CalculatorController.java create mode 100644 src/main/java/calculator/model/Expression.java create mode 100644 src/main/java/calculator/service/CalculatorService.java create mode 100644 src/main/java/calculator/service/CalculatorServiceImpl.java create mode 100644 src/main/java/calculator/view/InputView.java create mode 100644 src/main/java/calculator/view/OutputView.java diff --git a/src/main/java/calculator/controller/CalculatorController.java b/src/main/java/calculator/controller/CalculatorController.java new file mode 100644 index 0000000..4636390 --- /dev/null +++ b/src/main/java/calculator/controller/CalculatorController.java @@ -0,0 +1,26 @@ +package calculator.controller; + +import calculator.model.Expression; +import calculator.service.CalculatorService; +import calculator.view.InputView; +import calculator.view.OutputView; + +public class CalculatorController { + InputView inputView; + OutputView outputView; + CalculatorService calculatorService; + Expression expression; + + public CalculatorController( + InputView inputView, OutputView outputView, CalculatorService calculatorService, Expression expression + ) { + this.inputView = inputView; + this.outputView = outputView; + this.calculatorService = calculatorService; + this.expression = expression; + } + + public void run() { + + } +} diff --git a/src/main/java/calculator/model/Expression.java b/src/main/java/calculator/model/Expression.java new file mode 100644 index 0000000..67f28a9 --- /dev/null +++ b/src/main/java/calculator/model/Expression.java @@ -0,0 +1,5 @@ +package calculator.model; + +public class Expression { + +} diff --git a/src/main/java/calculator/service/CalculatorService.java b/src/main/java/calculator/service/CalculatorService.java new file mode 100644 index 0000000..f5def9f --- /dev/null +++ b/src/main/java/calculator/service/CalculatorService.java @@ -0,0 +1,4 @@ +package calculator.service; + +public interface CalculatorService { +} diff --git a/src/main/java/calculator/service/CalculatorServiceImpl.java b/src/main/java/calculator/service/CalculatorServiceImpl.java new file mode 100644 index 0000000..6dc8bfe --- /dev/null +++ b/src/main/java/calculator/service/CalculatorServiceImpl.java @@ -0,0 +1,5 @@ +package calculator.service; + +public class CalculatorServiceImpl implements CalculatorService { + +} diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java new file mode 100644 index 0000000..d939b9c --- /dev/null +++ b/src/main/java/calculator/view/InputView.java @@ -0,0 +1,5 @@ +package calculator.view; + +public class InputView { + +} diff --git a/src/main/java/calculator/view/OutputView.java b/src/main/java/calculator/view/OutputView.java new file mode 100644 index 0000000..4a2a4b0 --- /dev/null +++ b/src/main/java/calculator/view/OutputView.java @@ -0,0 +1,4 @@ +package calculator.view; + +public class OutputView { +} From 49309e8d0c543467c8b123a42fcaa7041be7a961 Mon Sep 17 00:00:00 2001 From: moongua404 Date: Sun, 2 Feb 2025 14:12:38 +0900 Subject: [PATCH 3/8] =?UTF-8?q?feat(AppConfig):=20config=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - config 파일로 의존성 주입 --- src/main/java/calculator/AppConfig.java | 34 +++++++++++++++++++ src/main/java/calculator/Application.java | 10 +++++- .../controller/CalculatorController.java | 2 +- 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 src/main/java/calculator/AppConfig.java diff --git a/src/main/java/calculator/AppConfig.java b/src/main/java/calculator/AppConfig.java new file mode 100644 index 0000000..9d8d4e3 --- /dev/null +++ b/src/main/java/calculator/AppConfig.java @@ -0,0 +1,34 @@ +package calculator; + +import calculator.controller.CalculatorController; +import calculator.model.Expression; +import calculator.service.CalculatorServiceImpl; +import calculator.view.InputView; +import calculator.view.OutputView; + +public class AppConfig { + public InputView inputView() { + return new InputView(); + } + + public OutputView outputView() { + return new OutputView(); + } + + public CalculatorServiceImpl calculatorService() { + return new CalculatorServiceImpl(); + } + + public Expression expression() { + return new Expression(); + } + + public CalculatorController calculatorController() { + return new CalculatorController( + this.inputView(), + this.outputView(), + this.calculatorService(), + this.expression() + ); + } +} diff --git a/src/main/java/calculator/Application.java b/src/main/java/calculator/Application.java index 573580f..f9e2f88 100644 --- a/src/main/java/calculator/Application.java +++ b/src/main/java/calculator/Application.java @@ -1,7 +1,15 @@ package calculator; +import calculator.controller.CalculatorController; + public class Application { + static AppConfig appConfig; + static CalculatorController calculatorController; + public static void main(String[] args) { - // TODO: 프로그램 구현 + appConfig = new AppConfig(); + calculatorController = appConfig.calculatorController(); + + calculatorController.run(); } } diff --git a/src/main/java/calculator/controller/CalculatorController.java b/src/main/java/calculator/controller/CalculatorController.java index 4636390..a3634d0 100644 --- a/src/main/java/calculator/controller/CalculatorController.java +++ b/src/main/java/calculator/controller/CalculatorController.java @@ -21,6 +21,6 @@ public CalculatorController( } public void run() { - + } } From 5a2e45de0934d24ffa14afc6d4ff867377547228 Mon Sep 17 00:00:00 2001 From: moongua404 Date: Sun, 2 Feb 2025 20:31:14 +0900 Subject: [PATCH 4/8] =?UTF-8?q?feat(model):=20Expression=20=EB=AA=A8?= =?UTF-8?q?=EB=8D=B8=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 정적 팩터리 메서드를 통해 구분자 추출 - input view 구현 --- .../controller/CalculatorController.java | 1 + .../java/calculator/model/Expression.java | 39 ++++++++++++++++++- .../calculator/utils/MessageConstants.java | 16 ++++++++ src/main/java/calculator/view/InputView.java | 8 +++- src/test/java/calculator/ExpressionTest.java | 26 +++++++++++++ 5 files changed, 87 insertions(+), 3 deletions(-) create mode 100644 src/main/java/calculator/utils/MessageConstants.java create mode 100644 src/test/java/calculator/ExpressionTest.java diff --git a/src/main/java/calculator/controller/CalculatorController.java b/src/main/java/calculator/controller/CalculatorController.java index a3634d0..feba2b5 100644 --- a/src/main/java/calculator/controller/CalculatorController.java +++ b/src/main/java/calculator/controller/CalculatorController.java @@ -21,6 +21,7 @@ public CalculatorController( } public void run() { + String line = inputView.getExpression(); } } diff --git a/src/main/java/calculator/model/Expression.java b/src/main/java/calculator/model/Expression.java index 67f28a9..17d364b 100644 --- a/src/main/java/calculator/model/Expression.java +++ b/src/main/java/calculator/model/Expression.java @@ -1,5 +1,40 @@ package calculator.model; +import java.util.Arrays; +import java.util.HashSet; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + public class Expression { - -} + private HashSet operators; + private String expression; + + public static Expression parse(String line) { + Expression expression = new Expression(); + + line = line.trim(); + line = expression.extractOperators(line); + expression.expression = line; + + return expression; + } + + public HashSet getOperators() { + return operators; + } + + public String getExpression() { + return expression; + } + + private String extractOperators(String line) { + this.operators = new HashSet<>(); + this.operators.addAll(Arrays.asList(':', ',')); + Matcher matcher = Pattern.compile("^//(.)\\\\n(.*)").matcher(line); + if (matcher.find()) { + operators.add(matcher.group(1).charAt(0)); + return matcher.group(2); + } + return line; + } +} \ No newline at end of file diff --git a/src/main/java/calculator/utils/MessageConstants.java b/src/main/java/calculator/utils/MessageConstants.java new file mode 100644 index 0000000..25d5e9e --- /dev/null +++ b/src/main/java/calculator/utils/MessageConstants.java @@ -0,0 +1,16 @@ +package calculator.utils; + +public enum MessageConstants { + GUIDE_MESSAGE("덧셈할 문자열을 입력해 주세요."), + RESULT_MESSAGE("결과 : %d"); + + private final String message; + + MessageConstants(String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java index d939b9c..32edcac 100644 --- a/src/main/java/calculator/view/InputView.java +++ b/src/main/java/calculator/view/InputView.java @@ -1,5 +1,11 @@ package calculator.view; +import calculator.utils.MessageConstants; +import camp.nextstep.edu.missionutils.Console; + public class InputView { - + public String getExpression() { + System.out.println(MessageConstants.GUIDE_MESSAGE); + return Console.readLine(); + } } diff --git a/src/test/java/calculator/ExpressionTest.java b/src/test/java/calculator/ExpressionTest.java new file mode 100644 index 0000000..f1be707 --- /dev/null +++ b/src/test/java/calculator/ExpressionTest.java @@ -0,0 +1,26 @@ +package calculator; + +import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; +import static org.assertj.core.api.Assertions.assertThat; + +import calculator.model.Expression; +import org.junit.jupiter.api.Test; + +public class ExpressionTest { + @Test + void Extract_Separator() { + assertSimpleTest(() -> { + Expression expression = Expression.parse("//*\\n1*2*3"); + assertThat(expression.getOperators()).contains('*'); + assertThat(expression.getExpression()).isEqualTo("1*2*3"); + }); + } + + @Test + void No_Separator() { + assertSimpleTest(() -> { + Expression expression = Expression.parse("1,2,3"); + assertThat(expression.getExpression()).isEqualTo("1,2,3"); + }); + } +} From b02eec9a9479505c12f27813a97d3ef74e88fa7e Mon Sep 17 00:00:00 2001 From: moongua404 Date: Sun, 2 Feb 2025 23:46:26 +0900 Subject: [PATCH 5/8] =?UTF-8?q?feat(Controller):=20=EC=A0=84=EC=B2=B4=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Service를 쓸 필요가 없어서 삭제 - Controller의 run으로 전체 기능 연결 - View 및 Model 보완 - utils 보완 --- src/main/java/calculator/AppConfig.java | 6 ------ .../controller/CalculatorController.java | 9 ++++---- .../java/calculator/model/Expression.java | 21 +++++++++++++++++++ .../calculator/service/CalculatorService.java | 4 ---- .../service/CalculatorServiceImpl.java | 5 ----- src/main/java/calculator/utils/Validator.java | 13 ++++++++++++ src/main/java/calculator/view/InputView.java | 2 +- src/main/java/calculator/view/OutputView.java | 5 +++++ src/test/java/calculator/ExpressionTest.java | 8 +++++++ 9 files changed, 52 insertions(+), 21 deletions(-) delete mode 100644 src/main/java/calculator/service/CalculatorService.java delete mode 100644 src/main/java/calculator/service/CalculatorServiceImpl.java create mode 100644 src/main/java/calculator/utils/Validator.java diff --git a/src/main/java/calculator/AppConfig.java b/src/main/java/calculator/AppConfig.java index 9d8d4e3..40692a5 100644 --- a/src/main/java/calculator/AppConfig.java +++ b/src/main/java/calculator/AppConfig.java @@ -2,7 +2,6 @@ import calculator.controller.CalculatorController; import calculator.model.Expression; -import calculator.service.CalculatorServiceImpl; import calculator.view.InputView; import calculator.view.OutputView; @@ -15,10 +14,6 @@ public OutputView outputView() { return new OutputView(); } - public CalculatorServiceImpl calculatorService() { - return new CalculatorServiceImpl(); - } - public Expression expression() { return new Expression(); } @@ -27,7 +22,6 @@ public CalculatorController calculatorController() { return new CalculatorController( this.inputView(), this.outputView(), - this.calculatorService(), this.expression() ); } diff --git a/src/main/java/calculator/controller/CalculatorController.java b/src/main/java/calculator/controller/CalculatorController.java index feba2b5..075fccd 100644 --- a/src/main/java/calculator/controller/CalculatorController.java +++ b/src/main/java/calculator/controller/CalculatorController.java @@ -1,27 +1,26 @@ package calculator.controller; import calculator.model.Expression; -import calculator.service.CalculatorService; import calculator.view.InputView; import calculator.view.OutputView; public class CalculatorController { InputView inputView; OutputView outputView; - CalculatorService calculatorService; Expression expression; public CalculatorController( - InputView inputView, OutputView outputView, CalculatorService calculatorService, Expression expression + InputView inputView, OutputView outputView, Expression expression ) { this.inputView = inputView; this.outputView = outputView; - this.calculatorService = calculatorService; this.expression = expression; } public void run() { String line = inputView.getExpression(); - + expression = Expression.parse(line); + int result = expression.calculate(); + outputView.printResult(result); } } diff --git a/src/main/java/calculator/model/Expression.java b/src/main/java/calculator/model/Expression.java index 17d364b..b3d524f 100644 --- a/src/main/java/calculator/model/Expression.java +++ b/src/main/java/calculator/model/Expression.java @@ -1,9 +1,12 @@ package calculator.model; +import calculator.utils.Validator; import java.util.Arrays; import java.util.HashSet; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; +import java.util.stream.Collectors; public class Expression { private HashSet operators; @@ -27,6 +30,18 @@ public String getExpression() { return expression; } + public int calculate() { + List results = Arrays.stream(expression.split(getOperatorsRegex())).toList(); + results.forEach(Validator::validatePositiveInt); + try { + return results.stream() + .mapToInt(Integer::parseInt) + .reduce(0, Math::addExact); + } catch (Exception exception) { + throw new IllegalArgumentException("Invalid expression: " + expression, exception); + } + } + private String extractOperators(String line) { this.operators = new HashSet<>(); this.operators.addAll(Arrays.asList(':', ',')); @@ -37,4 +52,10 @@ private String extractOperators(String line) { } return line; } + + private String getOperatorsRegex() { + return operators.stream() + .map(ch -> "\\" + ch) // \같은 문자 처리 + .collect(Collectors.joining("|")); + } } \ No newline at end of file diff --git a/src/main/java/calculator/service/CalculatorService.java b/src/main/java/calculator/service/CalculatorService.java deleted file mode 100644 index f5def9f..0000000 --- a/src/main/java/calculator/service/CalculatorService.java +++ /dev/null @@ -1,4 +0,0 @@ -package calculator.service; - -public interface CalculatorService { -} diff --git a/src/main/java/calculator/service/CalculatorServiceImpl.java b/src/main/java/calculator/service/CalculatorServiceImpl.java deleted file mode 100644 index 6dc8bfe..0000000 --- a/src/main/java/calculator/service/CalculatorServiceImpl.java +++ /dev/null @@ -1,5 +0,0 @@ -package calculator.service; - -public class CalculatorServiceImpl implements CalculatorService { - -} diff --git a/src/main/java/calculator/utils/Validator.java b/src/main/java/calculator/utils/Validator.java new file mode 100644 index 0000000..bf9c715 --- /dev/null +++ b/src/main/java/calculator/utils/Validator.java @@ -0,0 +1,13 @@ +package calculator.utils; + +public class Validator { + public static void validatePositiveInt(String number) { + try { + if (Integer.parseInt(number) < 0) { + throw new NumberFormatException(); + } + } catch (Exception exception) { + throw new IllegalArgumentException("Invalid number: " + number); + } + } +} diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java index 32edcac..dcec2e9 100644 --- a/src/main/java/calculator/view/InputView.java +++ b/src/main/java/calculator/view/InputView.java @@ -5,7 +5,7 @@ public class InputView { public String getExpression() { - System.out.println(MessageConstants.GUIDE_MESSAGE); + System.out.println(MessageConstants.GUIDE_MESSAGE.getMessage()); return Console.readLine(); } } diff --git a/src/main/java/calculator/view/OutputView.java b/src/main/java/calculator/view/OutputView.java index 4a2a4b0..94df46b 100644 --- a/src/main/java/calculator/view/OutputView.java +++ b/src/main/java/calculator/view/OutputView.java @@ -1,4 +1,9 @@ package calculator.view; +import calculator.utils.MessageConstants; + public class OutputView { + public void printResult(int v) { + System.out.printf((MessageConstants.RESULT_MESSAGE.getMessage()) + "%n", v); + } } diff --git a/src/test/java/calculator/ExpressionTest.java b/src/test/java/calculator/ExpressionTest.java index f1be707..c0d8a05 100644 --- a/src/test/java/calculator/ExpressionTest.java +++ b/src/test/java/calculator/ExpressionTest.java @@ -23,4 +23,12 @@ void No_Separator() { assertThat(expression.getExpression()).isEqualTo("1,2,3"); }); } + + @Test + void Special_Separator() { + assertSimpleTest(() -> { + Expression expression = Expression.parse("//\\\\n1*2*3"); + assertThat(expression.getOperators()).contains('\\'); + }); + } } From aa7503dfde5f6e2360b474f31ac2728a5741f5fc Mon Sep 17 00:00:00 2001 From: moongua404 Date: Tue, 4 Feb 2025 21:30:25 +0900 Subject: [PATCH 6/8] =?UTF-8?q?fix(View):=20input=20=EB=B6=80=EC=A0=81?= =?UTF-8?q?=EC=A0=88=ED=95=9C=20=EC=9E=85=EB=A0=A5=20=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Console.readline함수를 try catch로 감싸서 예외처리 --- src/main/java/calculator/view/InputView.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/main/java/calculator/view/InputView.java b/src/main/java/calculator/view/InputView.java index dcec2e9..0d5b7ae 100644 --- a/src/main/java/calculator/view/InputView.java +++ b/src/main/java/calculator/view/InputView.java @@ -5,7 +5,11 @@ public class InputView { public String getExpression() { - System.out.println(MessageConstants.GUIDE_MESSAGE.getMessage()); - return Console.readLine(); + try { + System.out.println(MessageConstants.GUIDE_MESSAGE.getMessage()); + return Console.readLine(); + } catch (Exception exception) { + throw new IllegalArgumentException("Something went wrong on input process."); + } } } From d80f0e0c40a17d26c719d3d46d03001c3a411c5a Mon Sep 17 00:00:00 2001 From: moongua404 Date: Thu, 6 Feb 2025 23:20:07 +0900 Subject: [PATCH 7/8] =?UTF-8?q?fix(Model):=20Expression=20=EC=9D=B4?= =?UTF-8?q?=EC=8A=A4=EC=BC=80=EC=9D=B4=ED=94=84=20=EB=AC=B8=EC=9E=90=20?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Pattern.quote를 통해 이스케이프 문자 처리 --- src/main/java/calculator/model/Expression.java | 2 +- src/test/java/calculator/ApplicationTest.java | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/calculator/model/Expression.java b/src/main/java/calculator/model/Expression.java index b3d524f..02fabd2 100644 --- a/src/main/java/calculator/model/Expression.java +++ b/src/main/java/calculator/model/Expression.java @@ -55,7 +55,7 @@ private String extractOperators(String line) { private String getOperatorsRegex() { return operators.stream() - .map(ch -> "\\" + ch) // \같은 문자 처리 + .map((ch) -> Pattern.quote(ch.toString())) // \같은 문자 처리 .collect(Collectors.joining("|")); } } \ No newline at end of file diff --git a/src/test/java/calculator/ApplicationTest.java b/src/test/java/calculator/ApplicationTest.java index 93771fb..1b2db04 100644 --- a/src/test/java/calculator/ApplicationTest.java +++ b/src/test/java/calculator/ApplicationTest.java @@ -1,12 +1,12 @@ package calculator; -import camp.nextstep.edu.missionutils.test.NsTest; -import org.junit.jupiter.api.Test; - import static camp.nextstep.edu.missionutils.test.Assertions.assertSimpleTest; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import camp.nextstep.edu.missionutils.test.NsTest; +import org.junit.jupiter.api.Test; + class ApplicationTest extends NsTest { @Test void 커스텀_구분자_사용() { @@ -19,8 +19,8 @@ class ApplicationTest extends NsTest { @Test void 예외_테스트() { assertSimpleTest(() -> - assertThatThrownBy(() -> runException("-1,2,3")) - .isInstanceOf(IllegalArgumentException.class) + assertThatThrownBy(() -> runException("-1,2,3")) + .isInstanceOf(IllegalArgumentException.class) ); } From 5e30aca5a1ec1c6c301488ea3f8bd69780368167 Mon Sep 17 00:00:00 2001 From: moongua404 Date: Fri, 7 Feb 2025 14:43:18 +0900 Subject: [PATCH 8/8] =?UTF-8?q?refactor(model&utils):=20=EC=83=81=EC=88=98?= =?UTF-8?q?=20=EC=B6=94=EC=B6=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 예외 메시지 상수로 추출 - 기타 상수 모델 필드로 추출 --- .../java/calculator/model/Expression.java | 21 +++++++++++++------ .../calculator/utils/ExceptionConstants.java | 16 ++++++++++++++ src/main/java/calculator/utils/Validator.java | 4 +++- 3 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 src/main/java/calculator/utils/ExceptionConstants.java diff --git a/src/main/java/calculator/model/Expression.java b/src/main/java/calculator/model/Expression.java index 02fabd2..2a22aee 100644 --- a/src/main/java/calculator/model/Expression.java +++ b/src/main/java/calculator/model/Expression.java @@ -1,5 +1,6 @@ package calculator.model; +import calculator.utils.ExceptionConstants; import calculator.utils.Validator; import java.util.Arrays; import java.util.HashSet; @@ -12,6 +13,13 @@ public class Expression { private HashSet operators; private String expression; + private static final List DEFAULT_SEPARATOR = Arrays.asList(':', ','); + private static final String OR_DELIMITER = "|"; + private static final String CUSTOM_SEPARATOR_REGEX = "^//(.)\\\\n(.*)"; + + private static final int CUSTOM_SEPARATOR_INDEX = 1; + private static final int EXPRESSION_INDEX = 2; + public static Expression parse(String line) { Expression expression = new Expression(); @@ -38,17 +46,18 @@ public int calculate() { .mapToInt(Integer::parseInt) .reduce(0, Math::addExact); } catch (Exception exception) { - throw new IllegalArgumentException("Invalid expression: " + expression, exception); + throw new IllegalArgumentException( + ExceptionConstants.INVALID_EXPRESSION.getMessage() + expression, exception); } } private String extractOperators(String line) { this.operators = new HashSet<>(); - this.operators.addAll(Arrays.asList(':', ',')); - Matcher matcher = Pattern.compile("^//(.)\\\\n(.*)").matcher(line); + this.operators.addAll(DEFAULT_SEPARATOR); + Matcher matcher = Pattern.compile(CUSTOM_SEPARATOR_REGEX).matcher(line); if (matcher.find()) { - operators.add(matcher.group(1).charAt(0)); - return matcher.group(2); + operators.add(matcher.group(CUSTOM_SEPARATOR_INDEX).charAt(0)); + return matcher.group(EXPRESSION_INDEX); } return line; } @@ -56,6 +65,6 @@ private String extractOperators(String line) { private String getOperatorsRegex() { return operators.stream() .map((ch) -> Pattern.quote(ch.toString())) // \같은 문자 처리 - .collect(Collectors.joining("|")); + .collect(Collectors.joining(OR_DELIMITER)); } } \ No newline at end of file diff --git a/src/main/java/calculator/utils/ExceptionConstants.java b/src/main/java/calculator/utils/ExceptionConstants.java new file mode 100644 index 0000000..6773e42 --- /dev/null +++ b/src/main/java/calculator/utils/ExceptionConstants.java @@ -0,0 +1,16 @@ +package calculator.utils; + +public enum ExceptionConstants { + INVALID_EXPRESSION("덧셈할 문자열을 입력해 주세요."), + INVALID_NUMBER_COMPOSITION("결과 : %d"); + + private final String message; + + ExceptionConstants(String message) { + this.message = message; + } + + public String getMessage() { + return this.message; + } +} diff --git a/src/main/java/calculator/utils/Validator.java b/src/main/java/calculator/utils/Validator.java index bf9c715..73e1217 100644 --- a/src/main/java/calculator/utils/Validator.java +++ b/src/main/java/calculator/utils/Validator.java @@ -1,13 +1,15 @@ package calculator.utils; public class Validator { + + public static void validatePositiveInt(String number) { try { if (Integer.parseInt(number) < 0) { throw new NumberFormatException(); } } catch (Exception exception) { - throw new IllegalArgumentException("Invalid number: " + number); + throw new IllegalArgumentException(ExceptionConstants.INVALID_NUMBER_COMPOSITION.getMessage() + number); } } }