-
Notifications
You must be signed in to change notification settings - Fork 59
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
[계산기] 권민관 미션 1차 수정본 입니다! #25
base: mlngwan
Are you sure you want to change the base?
Changes from 37 commits
74f7544
903f21d
2823002
b0c6ed1
3bfb2cf
ed9a151
a082226
5352af0
2b11bab
cf79840
ec61541
b8751fc
ae57faf
6b1fde1
f7900c1
b1398c6
31642a6
63e45f6
d97a6c6
cfe56c3
eb5a102
fc96402
c175799
cab781b
127590a
a2f073b
6efad2c
b14e0b1
b01efb9
a333ec8
3e57660
76e6def
78c9949
d6e7d1c
40c8548
b115121
4fb6e5c
8de5ddc
4601969
f185842
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,65 @@ | ||
## Step1 & Step2 (초간단 계산기 구현 및 테스트) | ||
### 기능 요구사항 | ||
인자 2개를 받아 사칙연산을 할 수 있는 계산기를 구현한다. | ||
사칙연산과 매칭되는 4개의 메서드를 제공한다. | ||
계산된 결과는 정수를 반환한다. | ||
|
||
### 새로운 프로그래밍 요구사항 | ||
메인 메서드는 만들지 않는다. | ||
|
||
### 단위 테스트 | ||
작은 단위로 테스트 할 것. | ||
|
||
### ToDo | ||
- 사칙연산 구현하기 | ||
- 최대한 MVC 구조로 구현하기 | ||
- JUnit 공부하기 | ||
- JUnit 활용하기 | ||
- 단위 테스트 구현하기 | ||
|
||
## Step 3 (문자열 계산기) | ||
### 기능 요구사항 | ||
- 기본적으로 쉼표(,)나 콜론(:)을 구분자로 가지는 경우 | ||
- 기본 구분자로 분리한 각 숫자 합을 반환 | ||
- (예: "" => 0, "1,2" => 3, "1,2:3" => 6) | ||
- 커스텀 구분자 지정 가능, "//"와 "\n" 사이에 위치하는 문자를 사용하는 경우 | ||
-커스텀 구분자로 분리해서 각 숫자 합을 반환 | ||
- (예: "//;\n1;2;3" => 구분자:";", 결과로 6 반환) | ||
- 문자열 계산기에 숫자 이외의 값 전달 경우 RuntimeException 예외 throw | ||
- 문자열 계산기에 음수를 전달하는 경우 RuntimeException 예외 throw | ||
|
||
### 새로운 프로그래밍 요구사항 | ||
- 구현한 문자열 계산기가 예상한대로 작동하는지 JUnit5 활용하여 테스트 자동화 | ||
- 조금 더 복잡한 도메인 대상으로 테스트 작성 경험 | ||
|
||
### 기존 프로그래밍 요구사항 | ||
- 메인 메서드 작성하지 않기 | ||
|
||
### ToDo | ||
- 문자열 계산기 구현하기 | ||
- MVC 구조로 작성하기 | ||
- JUnit5 기반 테스트 작성하기 | ||
- 필요기능? | ||
- AssertJ 기반 테스트 작성하기 | ||
- AssertJ 관련 학습하기 | ||
- AssertJ로 구현하기 | ||
|
||
## Step4 리팩토링 | ||
### 코드 작성 시 주의할 점 | ||
- 클래스 첫 줄에는 개행 넣기 -> 코드 컨벤션 (개행 알아보기) | ||
- 코드에 EOF 발생 -> 무엇인지, 처리법 | ||
- 코드 내부에 사용하는 메서드의 접근 제어자 설정 | ||
- 상수 처리 및 네이밍 | ||
- 메서드 명은 동사로 시작하기 | ||
- static 사용이유 | ||
- test code 네이밍 알아보기 | ||
- test code given-when-then 알아보기 | ||
|
||
### 초간단 계산기 | ||
- 사용자의 입력에 따라서 해당 연산 실행하게 바꾸기 | ||
- 음수일 때 예외 추가 | ||
- 나누는 수가 0일때 예외 처리 | ||
- view에 로직을 처리하지 않게 하기 -> model에서 처리하기 | ||
|
||
### 문자열 계산기 | ||
- sum 메서드 처리 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
package simpleCalculator.controller; | ||
|
||
import simpleCalculator.model.Calculator; | ||
import simpleCalculator.model.StringCalculator; | ||
import simpleCalculator.view.InputView; | ||
import simpleCalculator.view.OutView; | ||
|
||
public class CalculatorController { | ||
|
||
private InputView inputView; | ||
private OutView outView; | ||
private Calculator calculator; | ||
private StringCalculator stringCalculator; | ||
|
||
public CalculatorController() { | ||
this.inputView = new InputView(); | ||
this.outView = new OutView(); | ||
this.calculator = new Calculator(); | ||
this.stringCalculator = new StringCalculator(); | ||
} | ||
|
||
private void runSimpleCalculator() { | ||
String input = inputView.getSimpleNumber(); | ||
calculator.setNumber(input); | ||
|
||
int resultAdd = calculator.addNumbers(); | ||
int resultSub = calculator.subNumbers(); | ||
int resultDiv = calculator.divideNumbers(); | ||
int resultMul = calculator.multipleNumbers(); | ||
|
||
outView.printResult(resultAdd); | ||
outView.printResult(resultSub); | ||
outView.printResult(resultDiv); | ||
outView.printResult(resultMul); | ||
} | ||
|
||
private void runStringCalculator() { | ||
String input = inputView.getStringNumber(); | ||
int result = stringCalculator.add(input); | ||
|
||
outView.printResult(result); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package simpleCalculator.model; | ||
|
||
public class Calculator { | ||
|
||
private static final int ZERO = 0; | ||
private static final int ONE = 1; | ||
private static final int TWO = 2; | ||
|
||
private int num1; | ||
private int num2; | ||
|
||
private boolean checkHowManyInput(String[] inputList) { | ||
return inputList.length != TWO; | ||
} | ||
|
||
private String[] splitList(String input) { | ||
return input.split(","); | ||
} | ||
|
||
private int convertToInt(String input) { | ||
int number = Integer.parseInt(input); | ||
if (number < ZERO) { | ||
throw new RuntimeException("음수는 입력할 수 없습니다."); | ||
} | ||
return number; | ||
} | ||
|
||
private int[] convertToIntList(String[] inputList) { | ||
try { | ||
int[] numberList = new int[inputList.length]; | ||
for (int i = ZERO; i < inputList.length; i++) { | ||
numberList[i] = convertToInt(inputList[i]); | ||
} | ||
return numberList; | ||
} catch (NumberFormatException e) { | ||
throw new RuntimeException("숫자가 아닌 다른 형식이 포함되어 있습니다."); | ||
} | ||
} | ||
|
||
public void setNumber(String input) { | ||
String[] inputList = splitList(input); | ||
if(checkHowManyInput(inputList)) { | ||
throw new RuntimeException("2개의 숫자를 입력해주세요."); | ||
} | ||
int[] numbers = convertToIntList(inputList); | ||
this.num1 = numbers[ZERO]; | ||
this.num2 = numbers[ONE]; | ||
} | ||
|
||
public int addNumbers() { | ||
return num1 + num2; | ||
} | ||
|
||
public int subNumbers() { | ||
return num1 - num2; | ||
} | ||
|
||
public int divideNumbers() { | ||
if (num2 == 0) { | ||
throw new RuntimeException("0으로 나누기는 불가합니다."); | ||
} | ||
return num1 / num2; | ||
} | ||
|
||
public int multipleNumbers() { | ||
return num1 * num2; | ||
} | ||
} | ||
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. EOF가 발생하네요 검색하셔서 해결해주세요~ 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. EOF에 대해 맞게 이해 했는지와 궁금한 점이 생겼습니다. 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. scanner.close()는 resource를 풀어주는 거라 다른 결이긴 합니다! |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package simpleCalculator.model; | ||
|
||
public class StringCalculator { | ||
|
||
private static final String SEPARATOR_DEFAULTS = ",|:"; | ||
private static final int ZERO = 0; | ||
|
||
private boolean checkBlank(String input) { | ||
return input == null || input.isEmpty(); | ||
} | ||
|
||
private String[] splitInput(String input) { | ||
if (input.startsWith("//")) { | ||
return splitByCustom(input); | ||
} | ||
return input.split(SEPARATOR_DEFAULTS); | ||
} | ||
|
||
private String[] splitByCustom(String input) { | ||
String[] separates = input.split("\n", 2); | ||
String custom = separates[ZERO].substring(2); | ||
return separates[1].split(custom); | ||
} | ||
|
||
private int[] listToInt(String[] inputList) { | ||
try { | ||
int[] numberList = new int[inputList.length]; | ||
for (int i = ZERO; i < inputList.length; i++) { | ||
numberList[i] = convertToInt(inputList[i]); | ||
} | ||
return numberList; | ||
} catch (NumberFormatException e) { | ||
throw new RuntimeException("숫자가 아닌 다른 형식이 포함되었습니다."); | ||
} | ||
} | ||
|
||
private int convertToInt(String input) { | ||
int number = Integer.parseInt(input); | ||
if (number < ZERO) { | ||
throw new RuntimeException("음수는 입력할 수 없습니다."); | ||
} | ||
return number; | ||
} | ||
|
||
private int sum(int[] inputList) { | ||
int total = ZERO; | ||
for (int number : inputList) { | ||
total += number; | ||
} | ||
return total; | ||
} | ||
|
||
public int add(String input) { | ||
if (checkBlank(input)) { | ||
return ZERO; | ||
} | ||
return sum(listToInt(splitInput(input))); | ||
} | ||
} | ||
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. 여기도 설정해서 수정해주세요~ 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,28 @@ | ||
package simpleCalculator.view; | ||
|
||
import java.util.Scanner; | ||
|
||
public class InputView { | ||
|
||
private Scanner scanner; | ||
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. private, 각각 차이는 무엇일까요? 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. private는 해당 클래스 내부에서만 접근 가능하게 만들어주는 접근 제어자 입니다. 위와 같이 이해하고 있는데 잘못된 부분이 있을까요? |
||
|
||
public InputView() { | ||
this.scanner = new Scanner(System.in); | ||
} | ||
|
||
public String getSimpleNumber() { | ||
System.out.println("계산할 내용을 입력해주세요.(숫자,연산자,숫자 형식)"); | ||
while (scanner.hasNextLine()) { | ||
return scanner.nextLine(); | ||
} | ||
return null; | ||
} | ||
|
||
public String getStringNumber() { | ||
System.out.println("기본(, :)이나 커스텀 구분자(;)를 가지는 문자열을 입력해주세요. (예: 1,2 => 3, //;\\n1;2;3 => 6 반환)"); | ||
while (scanner.hasNextLine()) { | ||
return scanner.nextLine(); | ||
} | ||
return null; | ||
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.
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. EOF를 잘못 이해하고 나름대로 resource를 풀어주려고 작성했습니다. |
||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
package simpleCalculator.view; | ||
|
||
public class OutView { | ||
|
||
public void printResult(int result) { | ||
System.out.println("계산 결과: " + result); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change | ||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,77 @@ | ||||||||||||
package calculator; | ||||||||||||
|
||||||||||||
import org.junit.jupiter.api.BeforeEach; | ||||||||||||
import org.junit.jupiter.api.DisplayName; | ||||||||||||
import org.junit.jupiter.api.Nested; | ||||||||||||
import org.junit.jupiter.api.Test; | ||||||||||||
import simpleCalculator.model.Calculator; | ||||||||||||
|
||||||||||||
import static org.junit.jupiter.api.Assertions.*; | ||||||||||||
|
||||||||||||
public class CalculatorTest { | ||||||||||||
|
||||||||||||
private static final int EXPECT_VALUE = 3; | ||||||||||||
private Calculator calculator; | ||||||||||||
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.
Suggested change
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. 수정 완료했습니다! |
||||||||||||
|
||||||||||||
@BeforeEach | ||||||||||||
void setCalculator() { | ||||||||||||
calculator = new Calculator(); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("연산기능 테스트") | ||||||||||||
@Nested | ||||||||||||
class functionTest { | ||||||||||||
|
||||||||||||
@DisplayName("더하기") | ||||||||||||
@Test | ||||||||||||
void testAdd() { | ||||||||||||
calculator.setNumber("1,2"); | ||||||||||||
assertEquals(EXPECT_VALUE, calculator.addNumbers()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("빼기") | ||||||||||||
@Test | ||||||||||||
void testSub() { | ||||||||||||
calculator.setNumber("4,1"); | ||||||||||||
assertEquals(EXPECT_VALUE, calculator.subNumbers()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("나누기") | ||||||||||||
@Test | ||||||||||||
void testDiv() { | ||||||||||||
calculator.setNumber("9,3"); | ||||||||||||
assertEquals(EXPECT_VALUE, calculator.divideNumbers()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("곱하기") | ||||||||||||
@Test | ||||||||||||
void testAMul() { | ||||||||||||
calculator.setNumber("3,1"); | ||||||||||||
assertEquals(EXPECT_VALUE, calculator.multipleNumbers()); | ||||||||||||
} | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("예외처리 테스트") | ||||||||||||
@Nested | ||||||||||||
class exceptionTest { | ||||||||||||
|
||||||||||||
@DisplayName("0으로 나누기를 시도한 경우") | ||||||||||||
@Test | ||||||||||||
void testDivideByZero() { | ||||||||||||
calculator.setNumber("10,0"); | ||||||||||||
assertThrows(RuntimeException.class, () -> calculator.divideNumbers()); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("입력을 2개 미만으로 시도한 경우") | ||||||||||||
@Test | ||||||||||||
void testInputUnderTwo() { | ||||||||||||
assertThrows(RuntimeException.class, () -> calculator.setNumber("1")); | ||||||||||||
} | ||||||||||||
|
||||||||||||
@DisplayName("입력을 2개 초과로 시도한 경우") | ||||||||||||
@Test | ||||||||||||
void testInputOverTwo() { | ||||||||||||
assertThrows(RuntimeException.class, () -> calculator.setNumber("1,2,3")); | ||||||||||||
} | ||||||||||||
} | ||||||||||||
} |
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.
해당 클래스 외에도 첫줄 개행 추가해주세요
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.
네 수정하겠습니다!