Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
1c5c20b
feat: 사칙연산 기능 구현
kju2405 Jun 9, 2023
31d64fe
feat: 저장소 구현
kju2405 Jun 9, 2023
d42a6d9
feat: 조회 기능 추가
kju2405 Jun 9, 2023
b36e927
style: Interface 메서드 제어자 삭제
kju2405 Jun 13, 2023
c0c1a07
refactor: 메뉴 출력 기능 분리
kju2405 Jun 14, 2023
14789d6
refactor: 입력하는 기능 분리
kju2405 Jun 14, 2023
ef5eeca
style: Record -> Records
kju2405 Jun 14, 2023
1bd816a
refactor: 출력할 결과들을 가져오는 기능과 보여주는 기능 분리
kju2405 Jun 14, 2023
2b75683
refactor: Output 패키지의 Show인터페이스 파일로 합침
kju2405 Jun 14, 2023
8e7fc67
refactor: 기능별 패키지 생성
kju2405 Jun 14, 2023
2324418
refactor: type보다 input이 더 명확한것 같아 변경
kju2405 Jun 14, 2023
71917d0
refactor: 결과 출력 기능 분리
kju2405 Jun 14, 2023
15ffeda
refactor: 입력받은 식 전처리 작업 기능 분리
kju2405 Jun 14, 2023
50b581d
refactor: 사칙연산의 기능만 수행하도록 분리
kju2405 Jun 14, 2023
d31597e
refactor: 식을 입력받고 결과값을 반환하는 기능만 수행, 나머지 기능은 내부적으로 감춤
kju2405 Jun 14, 2023
057119f
refactor: DI컨테이너 생성
kju2405 Jun 14, 2023
8e49f93
style: 명확하게 이름 변경
kju2405 Jun 16, 2023
1429b49
refactor: 공통부붐 메서드 추출
kju2405 Jun 16, 2023
0f7a612
refactor: enum추가하여 각 메뉴 선택을 명확하게 함
kju2405 Jun 16, 2023
c22e1c6
refactor: 개행 문자 객체에서 수행
kju2405 Jun 16, 2023
4f44f1b
refactor: stream으로 변환
kju2405 Jun 16, 2023
f8ef218
test: 사칙연산 테스트 코드 작성
kju2405 Jun 16, 2023
63e778c
test: 테스트 코드 삭제
kju2405 Jun 16, 2023
8f97f36
refactor: 계산 순서는 내부적으로 숨김
kju2405 Jun 16, 2023
eee0518
style: CalculateImpl -> Calculator
kju2405 Jun 16, 2023
cb39427
test: 사칙연산 우선순위 테스트 코드 작성
kju2405 Jun 16, 2023
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
6 changes: 6 additions & 0 deletions calculator/src/main/java/org/example/CalOrder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
package org.example;

public interface CalOrder {
public abstract void calPriorityFirst();
public abstract void calPrioritySecond();

Choose a reason for hiding this comment

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

interface의 메서드는 기본적으로 추상 메서드이기 때문에 abstract가 없어도 됩니다.

}
66 changes: 66 additions & 0 deletions calculator/src/main/java/org/example/Calculate.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package org.example;

import java.util.Stack;

public class Calculate implements CalOrder{

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.

주말인데 불구하고 리뷰 남겨주셔서 감사합니다!😄
남겨주신 리뷰 확인하며 수정하는도중에 궁금한 사항이 생겨서요.
혹시 나누기 연산을 시행했을때의 기능 말씀이신지 아니면 전체적으로 효율적이지 못한(?) 계산기 수행 로직이라 전체적인 변경이 필요한지 궁금해서요!
감사합니다!

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.

아하 자세하게 설명해주셔서 감사합니다!
말씀해주신 부분 생각해서 수정해보도록 하겠습니다!

Copy link

Choose a reason for hiding this comment

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

조금 더 추상화가 필요하다고 할 수 있겠네요 ㅎㅎ!
기능에 따라 여러 역할로 객체를 나누어 보는 건 어떨까요?

private String expression;
Stack<String> expressionStack = new Stack<>();
ExpressionRepository repository = new ExpressionRepository();
int result = 0;

public Calculate(String expression) {
this.expression = expression;
String[] expressionArr = expression.split(" ");
for (String inputVal : expressionArr) {
expressionStack.add(inputVal);
}
}

public void calculate(){
calPriorityFirst();
calPrioritySecond();
}

@Override
public void calPriorityFirst() {
for (int i = 1; i < expressionStack.size(); i+=2) {
if (expressionStack.get(i).equals("*")) {
multiply(i);
i -= 2;
} else if (expressionStack.get(i).equals("/")) {
divide(i);
i -= 2;
}
}
}

@Override
public void calPrioritySecond() {
result = Integer.parseInt(expressionStack.get(0));
for (int i = 1; i < expressionStack.size(); i += 2) {
if (expressionStack.get(i).equals("+")) {
result += Integer.parseInt(expressionStack.get(i + 1));
} else {
result -= Integer.parseInt(expressionStack.get(i + 1));
}
}
System.out.println(result);
repository.save(expression,result);
}

public void multiply(int idx){
result = Integer.parseInt(expressionStack.get(idx - 1)) * Integer.parseInt(expressionStack.get(idx + 1));
expressionStack.add(idx - 1, String.valueOf(result));
expressionStack.remove(idx);
expressionStack.remove(idx);
expressionStack.remove(idx);
}

public void divide(int idx) {
result = Integer.parseInt(expressionStack.get(idx - 1)) / Integer.parseInt(expressionStack.get(idx + 1));
expressionStack.add(idx - 1, String.valueOf(result));
expressionStack.remove(idx);
expressionStack.remove(idx);
expressionStack.remove(idx);
}
}
18 changes: 18 additions & 0 deletions calculator/src/main/java/org/example/ExpressionRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.example;

import java.util.ArrayList;
import java.util.List;

public class ExpressionRepository implements Repository {
private static List<String> store = new ArrayList<>();

@Override
public void save(String expression, int result) {
store.add(expression + " = " + result);
Copy link

Choose a reason for hiding this comment

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

요구사항 그대로 값을 저장하는 것도 좋지만,
추후에 출력되어야 할 값이 바뀔 경우를 고려해보는 건 어떨까요?

}

@Override
public List<String> getRecord() {
return store;
}
Copy link

Choose a reason for hiding this comment

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

복수형을 반환하면 getRecords()가 좀 더 좋아보이네요

}
36 changes: 36 additions & 0 deletions calculator/src/main/java/org/example/Main.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package org.example;

import java.util.List;
import java.util.Scanner;

public class Main {
public static void main(String[] args) {

int choice = 0;

while (true) {
choice = getChoice();

Choose a reason for hiding this comment

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

변수의 불변성을 보장해주세요

System.out.println();
Copy link

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.

멘토님, 리뷰 감사드립니다!
혹시 show.showMenu()부분을 말씀하시는걸까요???

Copy link

Choose a reason for hiding this comment

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

System.out.println();으로 하드코딩 되어 있는 부분입니다 :)

Copy link
Author

@kju2405 kju2405 Jun 15, 2023

Choose a reason for hiding this comment

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

아하 감사합니다🙇‍♂️

if (choice == 1) {
Copy link

Choose a reason for hiding this comment

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

choice 1이 어떤 동작인지 어떻게 알 수 있을까요?

new UserInterfaceImpl().showRecord();

Choose a reason for hiding this comment

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

인터페이스가 아니라 구현체를 직접 사용하는게 적절한지 생각해보세요

} else {
String expression = typeExpression();
new Calculate(expression).calculate();

Choose a reason for hiding this comment

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

계산 한 번 할 때마다 계산기를 계속 생성해야할까요?

}
System.out.println();
}
}

public static int getChoice() {
Scanner scanner = new Scanner(System.in);

System.out.println("1. 조회\n2. 계산\n");
System.out.print("선택 : ");
return scanner.nextInt();
}

public static String typeExpression() {
Scanner scanner = new Scanner(System.in);
return scanner.nextLine();
}
Copy link

Choose a reason for hiding this comment

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

비슷한 기능을 하는 메소드들을 다른 객체로 추출하는 건 어떨까요?

}
8 changes: 8 additions & 0 deletions calculator/src/main/java/org/example/Repository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package org.example;

import java.util.List;

public interface Repository {
void save(String expression, int result);
List<String> getRecord();
}
5 changes: 5 additions & 0 deletions calculator/src/main/java/org/example/UserInterface.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package org.example;

public interface UserInterface {
public abstract void showRecord();
}
13 changes: 13 additions & 0 deletions calculator/src/main/java/org/example/UserInterfaceImpl.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package org.example;

import java.util.List;

public class UserInterfaceImpl implements UserInterface{

ExpressionRepository repository = new ExpressionRepository();
@Override
public void showRecord() {
List<String> record = repository.getRecord();
record.forEach(System.out::println);
}
Copy link

Choose a reason for hiding this comment

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

값을 가져오는 것과, 값을 출력하는 기능은 여러 기능을 한 번에 수행하는 것 처럼 보여요.

}