Skip to content

[이예진] 계산기 구현 2,3,4단계 #89

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

Open
wants to merge 8 commits into
base: yaevrai
Choose a base branch
from

Conversation

yaevrai
Copy link

@yaevrai yaevrai commented Apr 30, 2025

계산기 2-4단계 미션 제출합니다. 문자열 계산기 구현 시작이 어려워 먼저 다른 분 들이 하신 걸 봤습니다🥹
readme 파일에 요구사항을 작성하신 분들을 따라 저도 작성해 보았습니다.

질문

  1. readme 파일 작성할 때, 실제 프로젝트나 스터디 같은 여러 상황에서 가져가야하는 기준이 따로 있을지 혹은 어느 상황에서든 저의 코드를 볼 사람에게 내용을 안내해준다 생각하고 작성하면 될지 궁금합니다
  1. 저는 항상 설계나 큰 순서를 그리는 게 어려워 바텀업 방식으로 코드를 작성하는 경향이 있는 것 같습니다. 그러면서 종종 요구사항을 놓치기도 하고 비효율 적이란 생각을 하는데요😱 글렌은 어떠한 기능을 구현할 때 우선 사고하는 순서나 방식이 있나요?
  1. 구현할 때 기본적으로 꼭 고려해야한다고 생각하는 부분들에 대해 알려주실 수 있나요? 이번에 계산기를 구현하면서 계산만을 하는 기능에 대한 코드를 작성하는 건데 서비스, 유틸등의 레이어를 구분하는게 맞나? 어디까지 생각해야하지? 지금 구현한 게 객체지향적인가? 라는 고민들을 했습니다. 어떤 걸 구현하더라도 꼭 가져가야하는 게 있을 지 다른분의 생각을 들어보고싶어요!

Copy link

@seokjin8678 seokjin8678 left a comment

Choose a reason for hiding this comment

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

안녕하세요 예진님! 4단계까지 한 번에 하시느라 고생하셨습니다!
안타까운 소식이지만, 지금 작업 하신 브랜치가 병합하려는 브랜치와 충돌이 발생하고 있어요 😂
우선 간단하게 해결 방법에 대해 알려드릴게요.

  1. 인텔리제이 터미널 실행 (하단 Terminal 탭)
  2. git checkout yaevrai
  3. git remote -v 입력 후 도메인이 https://github.com/next-step/java-calculator-unit-playground.git인 넥스트스탭 remote 명 찾기 (nextstep 레포)
    만약 해당 도메인이 없다면 git remote add {nextstep remote} https://github.com/next-step/java-calculator-unit-playground.git 입력
  4. git rebase {찾은 remote 이름}/yaevari
  5. git remote -v 입력 후 도메인이 https://github.com/yaevrai/java-calculator-unit-playground.git인 본인 remote 찾기 (포크한 본인의 레포)
  6. git push {본인 remote} +head

해당 작업 완료하시고 다시 요청주세요!
그리고 리뷰 기다리시는 동안 위에 제가 적어뒀던 깃 명령어에 대해 알아보시면 좋을 것 같아요! (merge, rebase, force push, head, remote...)

@yaevrai yaevrai closed this Apr 30, 2025
@yaevrai yaevrai deleted the yaevrai branch April 30, 2025 06:51
@yaevrai yaevrai restored the yaevrai branch April 30, 2025 06:53
@yaevrai yaevrai reopened this Apr 30, 2025
Copy link

@seokjin8678 seokjin8678 left a comment

Choose a reason for hiding this comment

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

안녕하세요 예진님! 4단계까지 한 번에 해주셨군요! 👍👍
덕분에 한 번에 리뷰할 수 있어 편했습니다. 😂
우선 질문 남겨주신 것에 답변 드릴게요! (주관적인 제 답변이니 적당히 걸러서 들으시길..)

답변

  1. readme 파일 작성할 때, 실제 프로젝트나 스터디 같은 여러 상황에서 가져가야하는 기준이 따로 있을지 혹은 어느 상황에서든 저의 코드를 볼 사람에게 내용을 안내해준다 생각하고 작성하면 될지 궁금합니다

작은 프로젝트나 하나의 작업을 수행하는 간단한 프로그램의 경우 README에 어떠한 프로그램이고 어떠한 동작을 하는지 적어두는 것이 좋다고 생각해요. 지금 같은 미션도 규모가 그렇게 크지 않으니 README에 어떠한 역할을 하는지 작성하는 것은 좋아 보여요.
다만, 실제 프로젝트를 하면 규모가 매우 커지기 마련인데, 이 경우 README에 모든 내용은 담을 수 없으니 다른 문서화 도구를 선택해야겠죠?
이것은 주관적이니 문서화 도구를 선택하는 것은 진행되는 프로젝트의 인원에 따라 결정하면 될 것 같아요!

  1. 저는 항상 설계나 큰 순서를 그리는 게 어려워 바텀업 방식으로 코드를 작성하는 경향이 있는 것 같습니다. 그러면서 종종 요구사항을 놓치기도 하고 비효율 적이란 생각을 하는데요😱 글렌은 어떠한 기능을 구현할 때 우선 사고하는 순서나 방식이 있나요?

저 또한 바텀업 방식으로 먼저 구현하는 경향이 있어요. 그리고 기능 구현에 몰입하다 디테일에 매몰되어 다른 요구사항을 놓치는 일이 많아요 😂
우선 기능을 개발하기 전에 요구사항이 존재할 것이고, 이 요구사항을 정리해 두면 놓쳤던 부분을 찾을 수 있더라구요.
무조건 첫 시작은 탑다운, 바텀업을 고집할 필요는 없고, 상황에 맞춰서 선택하는 게 좋지 않을까요? (바텀업으로 집중하다 흐름을 놓치는 것 같으면 탑다운)

  1. 구현할 때 기본적으로 꼭 고려해야한다고 생각하는 부분들에 대해 알려주실 수 있나요? 이번에 계산기를 구현하면서 계산만을 하는 기능에 대한 코드를 작성하는 건데 서비스, 유틸등의 레이어를 구분하는게 맞나? 어디까지 생각해야하지? 지금 구현한 게 객체지향적인가? 라는 고민들을 했습니다. 어떤 걸 구현하더라도 꼭 가져가야하는 게 있을 지 다른분의 생각을 들어보고싶어요!

음.. 상황에 따라 다를 것 같아요.
만드는 기능이 어디선가 자주 사용되는 기능이고, 꽤 중요할 것이라는 확률이 높아 보인다면 재사용하기 쉽고, 읽기 좋게 만드는 것에 집중할 것 같아요. 하지만 그게 아니라 어디서 사용되지 않을 것 같고, 중요성이 낮은 기능이라면 굳이 집중해서 만들 필요가 없겠죠?
처음부터 잘 만들 생각은 하지 않고, 우선 맘에 들지 않더라도 돌아가는 코드를 만들어 보는 것도 나쁘지는 않은 것 같아요.
만약 미래에 이 코드를 확장해야 하거나, 수정해야 하는 경우 지웠다가 다시 만드는 게 더 나은 결과가 나올 수 있다고 생각해요.
오히려 처음부터 시간과 노력을 들여 객체 지향적이고 유지보수가 쉬운 코드를 작성하겠다고 했지만, 미래의 요구사항에 수용할 수 없어, 억지로로 구조에 짜맞춰야 하는 상황이 발생할 수 있어요.
그래도 이러한 구조적 고민을 해보는 것은 충분한 가치가 있다고 생각해요.
특히 미션은 운영할 서비스가 아니니, 이 시간만큼은 여러 시도를 해보면 좋을 것 같아요.


몇 요구사항은 지켜지지 않은 것 같아요!
리뷰로 남겼으니 확인해주시고 다시 요청 부탁드립니다!

Comment on lines +4 to +30

## level1
### 간단한 사칙연산 계산기 구현

요구사항
- 인자 2개를 받아 사칙연산을 할 수 있는 계산기를 구현한다.
- 사칙연산과 매칭되는 4개의 메서드를 제공한다.
- 계산된 결과는 정수를 반환한다.

## level2
### 구현한 사칙연산 계산기 테스트

요구사항
- 구현한 초간단 계산기가 예상한대로 동작하는지 Junit5를 활용하여 테스트를 자동화한다.


## level3
### 문자열 계산기 구현
요구사항
- 쉼표(,) 또는 콜론(:)을 구분자로 가지는 문자열을 전달하는 경우 구분자를 기준으로 분리한 각 숫자의 합을 반환 (예: “” => 0, "1,2" => 3, "1,2,3" => 6, “1,2:3” => 6)
- 앞의 기본 구분자(쉼표, 콜론)외에 커스텀 구분자를 지정할 수 있다. 커스텀 구분자는 문자열 앞부분의 “//”와 “\n” 사이에 위치하는 문자를 커스텀 구분자로 사용한다. 예를 들어 “//;\n1;2;3”과 같이 값을 입력할 경우 커스텀 구분자는 세미콜론(;)이며, 결과 값은 6이 반환되어야 한다.
- 문자열 계산기에 숫자 이외의 값 또는 음수를 전달하는 경우 RuntimeException 예외를 throw한다.

## level4
### 문자열 계산기 구현 리팩토링
- 기존 JUnit5로 작성되어 있던 단위 테스트를 AssertJ로 리팩터링한다.
JUnit5에서 제공하는 기능과 AssertJ에서 제공하는 기능을 사용해보고, 어떠한 차이가 있는지 경험한다.

Choose a reason for hiding this comment

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

요구사항 정리 👍
추후 이 문서가 이정표가 되어 줄 것 같네요!

Choose a reason for hiding this comment

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

2단계 미션을 진행해주셨군요!
다만, 2단계 미션의 경우 JUnit5를 사용하여 테스트 코드를 작성하라고 되어 있는데, 테스트 코드에선 JUnit5를 사용하지 않은 것 같네요 😂

Comment on lines +18 to +20
assertEquals(calculator.calculate(input), 0);
assertThat(calculator.calculate(input)).isZero();
assertThat(calculator.calculate(input)).isEqualTo(0);

Choose a reason for hiding this comment

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

AssertJ와 JUnit5를 함께 사용하셨네요!
4단계 미션은 Junit5로 작성된 테스트를 AssertJ를 사용한 테스트로 바꾸는 요구사항이었어요!
JUnit5로 작성된 테스트 코드를 AssertJ로 바꿔주세요!
그리고 AssertJ로 바꾸면서 어떤 점을 느꼈는지 알려주세요!

Choose a reason for hiding this comment

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

또한 검증에 사용할 결과는 하나만 사용해도 충분할 것 같아요!

Suggested change
assertEquals(calculator.calculate(input), 0);
assertThat(calculator.calculate(input)).isZero();
assertThat(calculator.calculate(input)).isEqualTo(0);
int actual = calculator.calculate(input);
assertEquals(actual, 0);
assertThat(actual).isZero();
assertThat(actual).isEqualTo(0);

Comment on lines +11 to +21
@Test
@DisplayName("add")
void add_test() {
int a = 1;
int b = 2;
int expected = a + b;

int actual = calculator.add(1, 2);

assertEquals(expected, actual);
}

Choose a reason for hiding this comment

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

테스트의 이름을 정해주시려고 @DisplayName을 사용해주셨네요!
다만 테스트 이름이 너무 단순해보여요.
테스트가 하는 행동을 이름으로 표현할 수 없을까요?

Choose a reason for hiding this comment

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

테스트의 결과를 검증하려고 expected 변수를 만들어주셨네요!
다만 expected 변수를 만드는 로직과 테스트 할 대상인 calculator.add() 메서드의 내부 로직이 동일해 보여요.
테스트 하는 로직이 사칙연산이라 변경될 일이 없고 너무 간단하지만, 테스트 코드의 목적을 생각해볼 때 이러한 검증이 과연 의미가 있을까요?
그렇다면 어떠한 방법으로 검증을 해야할까요?

Comment on lines +39 to +45
@Test
@DisplayName("커스텀 구분자가 포함된 문자열을 입력하면 숫자만 분리해 합한다.")
void input_numbers_with_custom_separator() {
String input = "//*\n1;2,3";

assertThat(calculator.calculate(input)).isEqualTo(6);
}

Choose a reason for hiding this comment

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

커스텀 구분자는 * 같네요!
그런데 input에는 커스텀 구분자가 보이지 않아요 😂

Choose a reason for hiding this comment

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

추가로 음수가 들어오면 결과가 어떻게 나오는지 궁금해요!
ex) "1,-2,3"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants