Skip to content

[4기 - 황창현] 1~2주차 과제 : 계산기 구현 미션 제출합니다. #124

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

Merged
merged 35 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
32dbff1
initial commit
Hchanghyeon Jun 4, 2023
d91bdce
feat: 콘솔 Input, Output 기능 추가
Hchanghyeon Jun 4, 2023
8ad98a3
feat: 연산식 입력값 검증 기능, 테스트 구현
Hchanghyeon Jun 4, 2023
23dc0a5
feat: 연산 로직 구현 및 테스트 코드 작성
Hchanghyeon Jun 6, 2023
efbb334
refactor: 변하지 않는 상수값 final로 변경, return 값 wrapper에서 기본 타입으로 변경
Hchanghyeon Jun 6, 2023
f0f58f4
연산식 및 연산결과 저장소에 저장 기능 구현 및 테스트 코드 작성
Hchanghyeon Jun 6, 2023
46c8ed6
refactor: console에서의 sysout을 output으로 변경하여 분리하기
Hchanghyeon Jun 6, 2023
6a77258
chore: 불필요 파일 삭제, gitignore 수정
Hchanghyeon Jun 6, 2023
49d3967
chore: gitignore gradle 관련파일 추가
Hchanghyeon Jun 6, 2023
633856b
refactor: Console에서 Validation 의존성 분리, Console 싱글톤 구현, 에러메시지 Console로 구현
Hchanghyeon Jun 10, 2023
52acb08
refactor: 네이밍 전체 수정, else/else if 삭제 처리, if문 중괄호 처리
Hchanghyeon Jun 10, 2023
b74dfe1
refactor: 매직넘버 제거 및 메시지 분리
Hchanghyeon Jun 10, 2023
c3082d6
refactor: Operator enum으로 변경, Calculation 객체 분리, Calculation 관련 객체 메소…
Hchanghyeon Jun 12, 2023
3e384b2
fix: 계산 기능중 우선순위 연산자 비교 기능 수정
Hchanghyeon Jun 12, 2023
1e9b2f0
refactor: Validator 객체 분리, Validator 관련 객체 메소드 분리
Hchanghyeon Jun 12, 2023
f12ab71
fix: 우선순위 비교 기능 로직, 연산식 검증 로직 변경
Hchanghyeon Jun 12, 2023
31b2a60
refactor: 불필요한 개행 삭제, 필요하지 않은 메소드 삭제, 메소드 위치 변경
Hchanghyeon Jun 12, 2023
8a56824
refactor: Repository HashMap에서 Linked HashMap으로 변경, save 리턴 값으로 예외처리
Hchanghyeon Jun 12, 2023
0abccaa
refactor: 객체 생성시 인스턴스 매개변수 2개 이하로 수정
Hchanghyeon Jun 13, 2023
f65cd56
refactor: Assertions import 작업, ParameterizedTest 추가
Hchanghyeon Jun 13, 2023
6e8064a
feat: 요구 사항 분석 및 구현 내용 README file 생성
Hchanghyeon Jun 13, 2023
16861fd
refactor: 요구사항 분석 및 구현 내용 수정
Hchanghyeon Jun 13, 2023
76a6b03
refactor: README 가독성을 위해 양식 변경
Hchanghyeon Jun 13, 2023
6d768d9
refactor: 0으로 나눴을 때 예외처리 추가, 예외 처리 테스트 작성
Hchanghyeon Jun 14, 2023
89f2a2f
Merge branch 'main' of https://github.com/Hchanghyeon/java-calculator
Hchanghyeon Jun 14, 2023
5385e9a
refactor: 불필요한 개행 삭제, 사용하지 않는 import문 삭제, 개행 추가
Hchanghyeon Jun 14, 2023
08dbbcb
refactor: Repository formulaList 반환 값 방어적 복사로 수정
Hchanghyeon Jun 15, 2023
5546538
refactor: Repository 문자열 포멧팅 책임 컨트롤러로 이동, save 반환 로직 삭제
Hchanghyeon Jun 15, 2023
60e1335
refactor: 메서드를 통한 가독성 개선
Hchanghyeon Jun 15, 2023
c0d283b
refactor: 불필요 연산과 중복된 코드를 줄이고 하나의 객체로 수정, 검증 예외 처리 추가
Hchanghyeon Jun 15, 2023
cb0d3d0
refactor: Calculator 생성자의 접근 제어자 default에서 public으로 변경
Hchanghyeon Jun 15, 2023
09c72d7
refactor: Map을 이용한 enum 최적화, 연산자 찾는 메서드 네이밍 변경하여 가독성 개선
Hchanghyeon Jun 15, 2023
ed2afb1
refactor: 테스트코드를 위한 private에서 public으로 변경, Repository 테스트코드 수정
Hchanghyeon Jun 15, 2023
1259231
refactor: 불필요한 개행, 메서드 삭제
Hchanghyeon Jun 15, 2023
9dec394
refactor: 예외 테스트 코드 작성
Hchanghyeon Jun 15, 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
175 changes: 175 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
# Created by https://www.toptal.com/developers/gitignore/api/java,intellij,gradle
# Edit at https://www.toptal.com/developers/gitignore?templates=java,intellij,gradle

### Intellij ###
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio, WebStorm and Rider
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839

# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf

# AWS User-specific
.idea/**/aws.xml

# Generated files
.idea/**/contentModel.xml

# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml

# Gradle
.idea/**/gradle.xml
.idea/**/libraries

# Gradle and Maven with auto-import
# When using Gradle or Maven with auto-import, you should exclude module files,
# since they will be recreated, and may cause churn. Uncomment if using
# auto-import.
# .idea/artifacts
# .idea/compiler.xml
# .idea/jarRepositories.xml
# .idea/modules.xml
# .idea/*.iml
# .idea/modules
# *.iml
# *.ipr

.idea
gradle
gradlew
gradlew.bat

# CMake
cmake-build-*/

# Mongo Explorer plugin
.idea/**/mongoSettings.xml

# File-based project format
*.iws

# IntelliJ
out/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Cursive Clojure plugin
.idea/replstate.xml

# SonarLint plugin
.idea/sonarlint/

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

# Editor-based Rest Client
.idea/httpRequests

# Android studio 3.1+ serialized cache file
.idea/caches/build_file_checksums.ser

### Intellij Patch ###
# Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721

# *.iml
# modules.xml
# .idea/misc.xml
# *.ipr

# Sonarlint plugin
# https://plugins.jetbrains.com/plugin/7973-sonarlint
.idea/**/sonarlint/

# SonarQube Plugin
# https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
.idea/**/sonarIssues.xml

# Markdown Navigator plugin
# https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
.idea/**/markdown-navigator.xml
.idea/**/markdown-navigator-enh.xml
.idea/**/markdown-navigator/

# Cache file creation bug
# See https://youtrack.jetbrains.com/issue/JBR-2257
.idea/$CACHE_FILE$

# CodeStream plugin
# https://plugins.jetbrains.com/plugin/12206-codestream
.idea/codestream.xml

# Azure Toolkit for IntelliJ plugin
# https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
.idea/**/azureSettings.xml

### Java ###
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

### Gradle ###
.gradle
**/build/
!src/**/build/

# Ignore Gradle GUI config
gradle-app.setting

# Avoid ignoring Gradle wrapper jar file (.jar files are usually ignored)
!gradle-wrapper.jar

# Avoid ignore Gradle wrappper properties
!gradle-wrapper.properties

# Cache of project
.gradletasknamecache

# Eclipse Gradle plugin generated files
# Eclipse Core
.project
# JDT-specific (Eclipse Java Development Tools)
.classpath

### Gradle Patch ###
# Java heap dump
*.hprof

# End of https://www.toptal.com/developers/gitignore/api/java,intellij,gradle
19 changes: 19 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
plugins {
id 'java'
}

group = 'org.programmers.java'
version = '1.0-SNAPSHOT'

repositories {
mavenCentral()
}

dependencies {
testImplementation platform('org.junit:junit-bom:5.9.1')
testImplementation 'org.junit.jupiter:junit-jupiter'
}

test {
useJUnitPlatform()
}
2 changes: 2 additions & 0 deletions settings.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
rootProject.name = 'JavaCalculator'

14 changes: 14 additions & 0 deletions src/main/java/org/programmers/java/App.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.programmers.java;

import org.programmers.java.calculation.Calculation;
import org.programmers.java.repository.FormulaRepository;
import org.programmers.java.repository.FormulaMemoryRepository;

public class App {
public static void main(String[] args){
Calculation calculation = new Calculation();
Copy link
Member

Choose a reason for hiding this comment

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

calculation 명칭만 보고는 어떤 동작을 하는 객체인지 모르겠습니다! 좀 더 객체를 잘 대변할 수 있는 이름이면 좋을 것 같습니다! (DTO가 아니라면 동사로 표현하는게 좋습니다.!)

Copy link
Member Author

Choose a reason for hiding this comment

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

계산하는 부분에 대한 로직을 담는다고 생각하여 계산이라고 지은 것 같습니다! 다시 보니 너무 포괄적인 의미를 담고 있어서 변경하는게 좋을 것 같습니다! DTO가 아닌 객체들은 메소드처럼 동사로 표현하는 것이 좋을까요?! 객체는 뭔가 명사로 지어야된다는 말을 많이 들었어서요!

Copy link
Member

Choose a reason for hiding this comment

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

@Hchanghyeon 아! 제가 잘못 전달했네요! 동사가 아니고 명사가 맞습니다..😅 다만 객체인 만큼 어떤 동작을 하는 주체로 표현하면 좋을 것 같아요!

FormulaRepository formulaRepository = new FormulaMemoryRepository();
Calculator calculator = new Calculator(calculation, formulaRepository);
calculator.run();
}
}
73 changes: 73 additions & 0 deletions src/main/java/org/programmers/java/Calculator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package org.programmers.java;

import org.programmers.java.calculation.Calculation;
import org.programmers.java.console.Console;
import org.programmers.java.console.Input;
import org.programmers.java.console.Output;
import org.programmers.java.message.Error;
import org.programmers.java.message.FunctionSelect;
import org.programmers.java.repository.FormulaRepository;
import org.programmers.java.validator.Validator;

public class Calculator {
private boolean programStatus = true;
private final Input input;
private final Output output;
private final Calculation calculation;
private final FormulaRepository formulaRepository;

public Calculator(Calculation calculation, FormulaRepository formulaRepository){
this.input = Console.getInstance();
this.output = Console.getInstance();
this.calculation = calculation;
this.formulaRepository = formulaRepository;
}

void run() {
while (programStatus) {
output.menuMsg();
String selectNum = input.selectNumInput();
output.selectMsg(selectNum);
FunctionSelect selectMenu = getFunctionSelectNumber(selectNum);
switch (selectMenu) {
case CHECK:
output.getCalculationValues(formulaRepository.getFormulaList());
break;
case CALCULATION:
formulaCalculate();
break;
case EXIT:
output.exitMsg();
programStatus = false;
break;
case WRONGINPUT:
output.errorMsg(Error.SELECT_VALIDATION.getMsg());
break;
}
}
}

private FunctionSelect getFunctionSelectNumber(String selectNum) {
return FunctionSelect.findSelect(selectNum).orElse(FunctionSelect.WRONGINPUT);
}

private void formulaCalculate() {
String inputFormula = input.formulaInput();
Validator.formulaValidate(inputFormula);

String result = calculation.requestCalculate(inputFormula);
output.calculationValue(result);

String formulaAndResult = formattingFormula(inputFormula, result);
formulaRepository.save(formulaAndResult);
}

private String formattingFormula(String inputFormula, String result){
Copy link
Member

Choose a reason for hiding this comment

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

만약 저였다면 inputFormula와 result를 묶는 데이터 객체(DTO)를 만들고 toString 메서드를 포맷에 맞게 재정의해서 사용했을 것 같아요!

Copy link
Member Author

Choose a reason for hiding this comment

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

DTO에 대한 고민을 전혀 하지 못했던 것 같습니다! 고민을 해보면 생각보다 DTO가 쓰일 수 있는 부분이 많은 것 같더라구요! 한 번 사용해서 수정하겠습니다!

StringBuilder stringBuilder = new StringBuilder();
return stringBuilder
.append(inputFormula)
.append("=")
.append(result)
.toString();
}
}
20 changes: 20 additions & 0 deletions src/main/java/org/programmers/java/calculation/Calculation.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package org.programmers.java.calculation;

import java.util.*;

public class Calculation {
private final InfixToPostfixConverter infixToPostfixConverter;
private final PostfixCalculation postfixCalculation;

public Calculation() {
this.infixToPostfixConverter = new InfixToPostfixConverter();
this.postfixCalculation = new PostfixCalculation();
}

public String requestCalculate(String inputFormula){
String[] formulaList = inputFormula.split(" ");
List<String> postfixOperator = infixToPostfixConverter.convert(formulaList);
String result = postfixCalculation.calculate(postfixOperator);
return result;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package org.programmers.java.calculation;

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Deque;
import java.util.List;

public class InfixToPostfixConverter {
List<String> postfixOperator = new ArrayList<>();
Deque<String> operatorDeque = new ArrayDeque<>();

public List<String> convert(String[] formulaList){
for(String operatorOrOperand : formulaList){
operandAddInPostfix(operatorOrOperand);
checkOperatorToAddPostfix(operatorOrOperand);
}

while(operatorDeque.size() > 0){
postfixOperator.add(operatorDeque.removeLast());
}

return postfixOperator;
}

private void operandAddInPostfix(String operatorOrOperand){
if(Operator.isNumber(operatorOrOperand)){
postfixOperator.add(operatorOrOperand);
}
}

private void checkOperatorToAddPostfix(String operatorOrOperand) {
if (Operator.findSymbol(operatorOrOperand).isPresent()) {
checkOperatorStackAndCompare(operatorOrOperand);
}
}

private void checkOperatorStackAndCompare(String operatorOrOperand){
while (!operatorDeque.isEmpty() && comparePriorities(operatorOrOperand)) {
postfixOperator.add(operatorDeque.removeLast());
}

operatorDeque.add(operatorOrOperand);
}

private boolean comparePriorities(String operatorOrOperand){
return Operator.comparePriorities(operatorDeque.peekLast(), operatorOrOperand);
}
}
Loading