Skip to content
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단계 - 문자열 덧셈 계산기 #764

Merged
merged 17 commits into from
Jan 27, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
root = true

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍


[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
max_line_length = 120
tab_width = 4
41 changes: 41 additions & 0 deletions 1단계_요구사항.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
## 1단계 요구사항

- [x] 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환
- (예: “” => 0, "1,2" => 3, "1,2,3" => 6, “1,2:3” => 6)

- [x] 앞의 기본 구분자(쉼표, 콜론) 외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 “//”와 “\n” 사이에 위치하는 문자를 커스텀 구분자로 사용한다.
- 예를 들어 “//;\n1;2;3”과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.

- [x] 문자열 계산기에 숫자 이외의 값 또는 음수를 전달하는 경우 RuntimeException 예외를 throw 한다.

### 힌트(= 추가 요구 사항)

- [x] 빈 문자열 또는 null을 입력할 경우 0을 반환해야 한다. (예 : “” => 0, null => 0)

- [x] 숫자 하나를 문자열로 입력할 경우 해당 숫자를 반환한다.(예 : “1”)

- [x] 숫자 두개를 컴마(,) 구분자로 입력할 경우 두 숫자의 합을 반환한다. (예 : “1,2”)

- [x] 구분자를 컴마(,) 이외에 콜론(:)을 사용할 수 있다. (예 : “1,2:3” => 6)

- [x] "//"와 "\n" 문자 사이에 커스텀 구분자를 지정할 수 있다. (예 : “//;\n1;2;3” => 6

- [x] 음수를 전달할 경우 RuntimeException 예외가 발생해야 한다. (예 : “-1,2,3”)

## 커밋 컨벤션

- 커밋 메시지 작성법은 [AngularJS Git Commit Message Conventions](https://gist.github.com/stephenparish/9941e89d80e2bc58a153) 을
원칙으로 작성한다.

```markdown
feat (feature)
fix (bug fix)
docs (documentation)
style (formatting, missing semi colons, …)
refactor
test (when adding missing tests)
chore (maintain)
```

## 참고자료
- [코드리뷰 요청을 위한 준비사항](https://github.com/next-step/nextstep-docs/tree/master/codereview)
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ docker compose -p kitchenpos up -d
## 용어 사전

| 한글명 | 영문명 | 설명 |
| --- | --- | --- |
| | | |
|-----|-----|----|
| | | |

## 모델링
32 changes: 16 additions & 16 deletions docker/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
name: kitchenpos
services:
db:
image: mysql:8.0.30
platform: linux/x86_64
restart: always
ports:
- "33306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: kitchenpos
MYSQL_USER: user
MYSQL_PASSWORD: password
TZ: Asia/Seoul
volumes:
- ./db/mysql/data:/var/lib/mysql
- ./db/mysql/config:/etc/mysql/conf.d
- ./db/mysql/init:/docker-entrypoint-initdb.d
db:
image: mysql:8.0.30
platform: linux/x86_64
restart: always
ports:
- "33306:3306"
environment:
MYSQL_ROOT_PASSWORD: root
MYSQL_DATABASE: kitchenpos
MYSQL_USER: user
MYSQL_PASSWORD: password
TZ: Asia/Seoul
volumes:
- ./db/mysql/data:/var/lib/mysql
- ./db/mysql/config:/etc/mysql/conf.d
- ./db/mysql/init:/docker-entrypoint-initdb.d
2 changes: 1 addition & 1 deletion http/menu-groups.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ POST {{host}}/api/menu-groups
Content-Type: application/json

{
"name": "추천메뉴"
"name": "추천메뉴"
}

###
Expand Down
22 changes: 11 additions & 11 deletions http/menus.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,24 +3,24 @@ POST {{host}}/api/menus
Content-Type: application/json

{
"name": "후라이드+후라이드",
"price": 19000,
"menuGroupId": "f1860abc-2ea1-411b-bd4a-baa44f0d5580",
"displayed": true,
"menuProducts": [
{
"productId": "3b528244-34f7-406b-bb7e-690912f66b10",
"quantity": 2
}
]
"name": "후라이드+후라이드",
"price": 19000,
"menuGroupId": "f1860abc-2ea1-411b-bd4a-baa44f0d5580",
"displayed": true,
"menuProducts": [
{
"productId": "3b528244-34f7-406b-bb7e-690912f66b10",
"quantity": 2
}
]
}

###
PUT {{host}}/api/menus/f59b1e1c-b145-440a-aa6f-6095a0e2d63b/price
Content-Type: application/json

{
"price": 15000
"price": 15000
}

###
Expand Down
4 changes: 2 additions & 2 deletions http/order-tables.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ POST {{host}}/api/order-tables
Content-Type: application/json

{
"name": "9번"
"name": "9번"
}

###
Expand All @@ -17,7 +17,7 @@ PUT {{host}}/api/order-tables/8d710043-29b6-420e-8452-233f5a035520/number-of-gue
Content-Type: application/json

{
"numberOfGuests": 4
"numberOfGuests": 4
}

###
Expand Down
18 changes: 9 additions & 9 deletions http/orders.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@ POST {{host}}/api/orders
Content-Type: application/json

{
"type": "EAT_IN",
"orderTableId": "8d710043-29b6-420e-8452-233f5a035520",
"orderLineItems": [
{
"menuId": "f59b1e1c-b145-440a-aa6f-6095a0e2d63b",
"price": 16000,
"quantity": 3
}
]
"type": "EAT_IN",
"orderTableId": "8d710043-29b6-420e-8452-233f5a035520",
"orderLineItems": [
{
"menuId": "f59b1e1c-b145-440a-aa6f-6095a0e2d63b",
"price": 16000,
"quantity": 3
}
]
}

###
Expand Down
6 changes: 3 additions & 3 deletions http/products.http
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,16 @@ POST {{host}}/api/products
Content-Type: application/json

{
"name": "강정치킨",
"price": 17000
"name": "강정치킨",
"price": 17000
}

###
PUT {{host}}/api/products/3b528244-34f7-406b-bb7e-690912f66b10/price
Content-Type: application/json

{
"price": 18000
"price": 18000
}

###
Expand Down
6 changes: 3 additions & 3 deletions rest-client.env.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"local": {
"host": "localhost:8080"
}
"local": {
"host": "localhost:8080"
}
}
39 changes: 39 additions & 0 deletions src/main/java/calculator/PositiveNumber.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package calculator;

import calculator.exception.InvalidNumberFormatException;
import calculator.exception.NegativeNumberException;

/**
* 숫자 검증 및 변환하는 역할
*/
public class PositiveNumber {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

책임에 맞게 객체를 분리했으니, 테스트 코드도 분리할 수 있을 것 같아요.


private final int value;

public PositiveNumber(final String text) {

if (!isNumeric(text)) {
throw new InvalidNumberFormatException("Invalid input: Non-numeric value found: " + text);
}

int number = Integer.parseInt(text);

if (number < 0) {
throw new NegativeNumberException("Negative numbers are not allowed: " + number);
}
this.value = number;
}

private boolean isNumeric(final String text) {
try {
Integer.parseInt(text);
return true;
} catch (NumberFormatException e) {
return false;
}
}

public int getValue() {
return value;
}
}
29 changes: 29 additions & 0 deletions src/main/java/calculator/StringAdditionCalculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package calculator;

import calculator.exception.PositiveNumbers;

import java.util.List;

/**
* 입력된 문자열을 처리하고 결과를 반환하는 역할
*/
public class StringAdditionCalculator {

private final String text;

public StringAdditionCalculator(final String text) {
this.text = text;
}

public int add() {
if (text == null || text.isEmpty()) {
return 0;

}

List<String> numbers = StringSplitter.split(text);
PositiveNumbers positiveNumbers = new PositiveNumbers(numbers);
return positiveNumbers.sum();
}
}

31 changes: 31 additions & 0 deletions src/main/java/calculator/StringSplitter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package calculator;

import java.util.Arrays;
import java.util.List;

public class StringSplitter {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

생성자의 접근 제한자를 private으로 설정하면 유틸리티 클래스가 인스턴스화되는 것을 방지할 수 있습니다.

Suggested change
public class StringSplitter {
private StringSplitter() {
}

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

유틸리티 클래스를 명확히 표현하기 위해 접근 제한자 부분까지 신경써야 한다는 점을 잊고 있었네요 ! 꼼꼼한 피드백 감사드려요!

Copy link

@mj950425 mj950425 Jan 27, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반영이 안되어있네요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아래와 같이 생성자를 private로 반영했어요 !

private StringSplitter() {
        throw new UnsupportedOperationException("StringSplitter is a utility class and cannot be instantiated.");
    }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아하 제가 코드 확인을 못한 것 같습니다. 잘 반영해주셨네요 👍


private static final String DEFAULT_DELIMITERS = ",|:";
public static final String CUSTOM_DELIMITER_PREFIX = "//";
public static final String CUSTOM_DELIMITER_SUFFIX = "\n";

private StringSplitter() {
throw new UnsupportedOperationException("StringSplitter is a utility class and cannot be instantiated.");
}

public static List<String> split(final String inputText) {

// check for custom delimiter
if (inputText.startsWith(CUSTOM_DELIMITER_PREFIX)) {
int customDelimiterEndIndex = inputText.indexOf(CUSTOM_DELIMITER_SUFFIX);
String customDelimiter = inputText.substring(CUSTOM_DELIMITER_PREFIX.length(), customDelimiterEndIndex);
String numberSection = inputText.substring(customDelimiterEndIndex + CUSTOM_DELIMITER_SUFFIX.length());
return Arrays.asList(numberSection.split(customDelimiter));
}

// default delimiters
return Arrays.asList(inputText.split(DEFAULT_DELIMITERS));
}
}


Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package calculator.exception;

public class InvalidNumberFormatException extends RuntimeException {

public InvalidNumberFormatException(final String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package calculator.exception;

public class NegativeNumberException extends RuntimeException {
public NegativeNumberException(final String message) {
super(message);
}
}
26 changes: 26 additions & 0 deletions src/main/java/calculator/exception/PositiveNumbers.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package calculator.exception;

import calculator.PositiveNumber;

import java.util.List;
import java.util.stream.Collectors;

/**
* 0 이상의 숫자들의 리스트를 관리하는 일급 컬렉션
*/
public class PositiveNumbers {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

잘 만들어주셨네요 👍

만들어주신 일급 컬랙션도 테스트 코드를 만들 수 있을 것 같네요.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분은 2단계 미션 진행하면서 같이 짜보도록 할게요!


private final List<PositiveNumber> numbers;

public PositiveNumbers(final List<String> numberToStrings) {
this.numbers = numberToStrings.stream()
.map(PositiveNumber::new)
.collect(Collectors.toList());

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바 21을 사용하고 계시네요.

자바 16부터는 이렇게 고칠 수 있어요.

Suggested change
.collect(Collectors.toList());
.toList();

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

자바 11 이후의 문법을 아직까지 몰랐는데, 미션을 진행해보면서 틈틈히 공부해봐야겠네요!
꼼꼼한 피드백 감사드려요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2단계 미션에 반영해두겠습니다!

}

public int sum() {
return numbers.stream()
.mapToInt(PositiveNumber::getValue)
.sum();
}
}
10 changes: 5 additions & 5 deletions src/main/java/racingcar/Car.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ public Car(String name) {
this.name = name;
}

public int getPosition() {
return position;
}

public void move(final MovingStrategy moveingStrategy) {
if (moveingStrategy.movable()) {
if (moveingStrategy.movable()) {
position++;
}
}

public int getPosition() {
return position;
}
}
Loading