-
Notifications
You must be signed in to change notification settings - Fork 155
[4기 - 강병곤] 1~2주차 과제 : 계산기 구현 미션 제출합니다. #189
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
base: Curry4182
Are you sure you want to change the base?
Changes from all commits
ea304be
610619a
bf3f864
218140d
bbd270b
4b4de21
de08a26
8a8d6c2
9c15fa9
3c3a5e2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| package calcproject.di.container; | ||
|
|
||
| import calcproject.engine.Calculator; | ||
| import calcproject.factory.CalcManagerViewFactory; | ||
| import calcproject.factory.CalcResultRecordRepositoryFactory; | ||
| import calcproject.repository.CalcResultRecordRepository; | ||
| import calcproject.service.CalcManager; | ||
| import calcproject.view.CalcInput; | ||
| import calcproject.view.CalcOutput; | ||
|
|
||
| public class CalcManagerDependencyInjectionContainer { | ||
|
|
||
| private CalcResultRecordRepositoryFactory calcResultRecordRepositoryFactory; | ||
|
|
||
| private CalcManagerViewFactory calcManagerViewFactory; | ||
|
|
||
| private Calculator calculator; | ||
|
|
||
| public CalcManagerDependencyInjectionContainer( | ||
| CalcResultRecordRepositoryFactory calcResultRecordRepositoryFactory, | ||
| CalcManagerViewFactory calcManagerViewFactory, | ||
| Calculator calculator | ||
| ) { | ||
| this.calcResultRecordRepositoryFactory = calcResultRecordRepositoryFactory; | ||
| this.calcManagerViewFactory = calcManagerViewFactory; | ||
| this.calculator = calculator; | ||
| } | ||
|
|
||
| public CalcManager createCalcManager() { | ||
| CalcResultRecordRepository calcResultRecordRepository = | ||
| calcResultRecordRepositoryFactory.createCalcResultRecordRepository(); | ||
|
|
||
| CalcInput calcInput = | ||
| calcManagerViewFactory.createCalcInput(); | ||
|
|
||
| CalcOutput calcOutput = | ||
| calcManagerViewFactory.createCalcOutput(); | ||
|
|
||
| CalcManager calcManager = new CalcManager( | ||
| calcResultRecordRepository, | ||
| calcInput, | ||
| calcOutput, | ||
| this.calculator | ||
| ); | ||
|
|
||
| return calcManager; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,30 @@ | ||
| package calcproject.engine; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
|
|
||
| public class CalcExpressionTokenizer { | ||
| public List<String> tokenizeExpression(String expression) { | ||
| return null; | ||
| List<String> tokens = new ArrayList<>(); | ||
| StringBuilder sb = new StringBuilder(); | ||
|
|
||
| for (char element : expression.toCharArray()) { | ||
| if (Character.isDigit(element)) { | ||
| sb.append(element); | ||
| } else { | ||
| String numberString = sb.toString(); | ||
| tokens.add(numberString); | ||
|
|
||
| sb.setLength(0); | ||
| tokens.add(Character.toString(element)); | ||
| } | ||
| } | ||
|
|
||
| if (sb.length() > 0) { | ||
| String numberString = sb.toString(); | ||
| tokens.add(numberString); | ||
|
Comment on lines
+24
to
+25
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. 반복되는 코드가 나오는 것 같은데 공통 메서드로 추출하는 건 어떠신가요? |
||
| } | ||
|
|
||
| return tokens; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| package calcproject.engine; | ||
|
|
||
| public interface Calculable { | ||
| public double calculate(double num1, double num2); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,8 @@ | ||
| package calcproject.engine; | ||
|
|
||
| import java.util.ArrayList; | ||
| import java.util.List; | ||
| import java.util.Stack; | ||
|
|
||
| public class Calculator { | ||
| private CalcExpressionTokenizer calcExpressionTokenizer; | ||
|
|
@@ -11,6 +13,72 @@ public Calculator(CalcExpressionTokenizer calcExpressionTokenizer) { | |
|
|
||
| public double calculateExpression(String expression) { | ||
| List<String> tokens = calcExpressionTokenizer.tokenizeExpression(expression); | ||
| return Double.NaN; | ||
| List<String> postfixTokens = toPostfixNotation(tokens); | ||
| double calcResult = calculatePostfixNotation(postfixTokens); | ||
|
|
||
| return calcResult; | ||
| } | ||
|
|
||
| public List<String> toPostfixNotation(List<String> tokens) { | ||
| Stack<String> stack = new Stack<>(); | ||
| List<String> postFixNotationTokens = new ArrayList<>(); | ||
|
|
||
| for (String currentToken : tokens) { | ||
| if (isNumber(currentToken)) { | ||
| postFixNotationTokens.add(currentToken); | ||
| continue; | ||
| } | ||
| while (!stack.empty()) { | ||
| Operator currentOperator = Operator.opValueOf(currentToken); | ||
| Operator stackPeekOPerator = Operator.opValueOf(stack.peek()); | ||
|
|
||
| if (stackPeekOPerator == Operator.UnSupportedOp) { | ||
| return List.of(); | ||
| } | ||
|
|
||
| if (currentOperator.getPriority() > stackPeekOPerator.getPriority()) { | ||
| break; | ||
| } | ||
|
|
||
| postFixNotationTokens.add(stack.pop()); | ||
| } | ||
|
|
||
| stack.add(currentToken); | ||
| } | ||
|
|
||
| while (!stack.empty()) { | ||
| postFixNotationTokens.add(stack.pop()); | ||
| } | ||
|
|
||
| return postFixNotationTokens; | ||
| } | ||
|
|
||
| public double calculatePostfixNotation(List<String> postFixNotationTokens) { | ||
| Stack<Double> stack = new Stack<>(); | ||
|
|
||
| for (String token : postFixNotationTokens) { | ||
|
|
||
| if (isNumber(token)) { | ||
| double num = Double.valueOf(token); | ||
| stack.push(num); | ||
| } else { | ||
| Operator operator = Operator.opValueOf(token); | ||
|
|
||
| double operand2 = stack.pop(); | ||
| double operand1 = stack.pop(); | ||
|
Comment on lines
+67
to
+68
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. stack이 비어있다면 어떻게 되나요? |
||
| double result = operator.calculate(operand1, operand2); | ||
| stack.push(result); | ||
| } | ||
| } | ||
|
|
||
| return stack.pop(); | ||
| } | ||
|
|
||
| private boolean isNumber(String token) { | ||
| for (int i = 0; i < token.length(); i++) { | ||
| if (!Character.isDigit(token.charAt(i))) | ||
| return false; | ||
| } | ||
| return true; | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package calcproject.engine; | ||
|
|
||
| import java.util.Arrays; | ||
|
|
||
| public enum Operator { | ||
| Plus("+", 0, (a, b) -> a + b), | ||
| Minus("-", 0, (a, b) -> a - b), | ||
| Multiply("*", 1, (a, b) -> a * b), | ||
| Divide("/", 1, (a, b) -> a / b), | ||
| UnSupportedOp("", -1, (a, b) -> Double.NaN); | ||
|
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. 반환 값으로 UnSupportedOp를 사용하게 되면 어떻게 되나요? |
||
|
|
||
| private String operator; | ||
| private int priority; | ||
| private Calculable calculable; | ||
|
|
||
| Operator(String operator, int priority, Calculable calculable) { | ||
| this.operator = operator; | ||
| this.priority = priority; | ||
| this.calculable = calculable; | ||
| } | ||
|
|
||
| public static Operator opValueOf(String op) { | ||
| return Arrays.stream(values()) | ||
| .filter( | ||
| value -> value | ||
| .getOperator() | ||
| .equals(op) | ||
| ) | ||
| .findAny() | ||
| .orElse(Operator.UnSupportedOp); | ||
| } | ||
|
|
||
| public String getOperator() { | ||
| return this.operator; | ||
| } | ||
|
|
||
| public int getPriority() { | ||
| return this.priority; | ||
| } | ||
|
|
||
| public double calculate(double num1, double num2) { | ||
| return this.calculable.calculate(num1, num2); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,9 +12,9 @@ public class MemoryCalcResultRecordRepository implements CalcResultRecordReposit | |
| private Map<Integer, CalcResultRecordModel> calcMap; | ||
|
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. 입력과 조회(모든 레코드) 두 가지 기능만 사용하고 있는데 굳이 Map을 쓰신 이유가 있나요? |
||
| private int lastIdx; | ||
|
|
||
| public MemoryCalcResultRecordRepository(Map<Integer, CalcResultRecordModel> calcMap, int startIdx) { | ||
| public MemoryCalcResultRecordRepository(Map<Integer, CalcResultRecordModel> calcMap) { | ||
| this.calcMap = calcMap; | ||
| this.lastIdx = startIdx; | ||
| this.lastIdx = 0; | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -27,7 +27,7 @@ public void saveCalcResultRecord(CalcResultRecordModel calcResultRecord) { | |
| public List<CalcResultRecordModel> loadCalcResultRecords() { | ||
| return this.calcMap.values() | ||
| .stream() | ||
| .sorted(Comparator.comparing(calcModel -> calcModel.getId())) | ||
| .sorted(Comparator.comparing(CalcResultRecordModel::getId)) | ||
| .collect(Collectors.toList()); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -54,4 +54,4 @@ private void executeCmd(Command cmd) { | |
| break; | ||
| } | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,7 +15,7 @@ public enum Command { | |
|
|
||
| public static Command valueOf(int choiceNum) { | ||
| return Arrays.stream(values()) | ||
| .filter(value -> value.equals(choiceNum)) | ||
| .filter(value -> value.getCmdIdx() == choiceNum) | ||
|
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. 비교하는 메서드를 따로 만드는건 어떨까요? |
||
| .findAny() | ||
| .orElse(CALCULATE.EXIT); | ||
|
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. CALCULATE.EXIT는 사용자 의도로 인해 종료한다는 느낌인데요 |
||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,20 +12,19 @@ | |
| public class CalcConsoleView implements CalcInput, CalcOutput { | ||
| private Scanner scanner; | ||
|
|
||
| public CalcConsoleView(Scanner scanner) { | ||
| this.scanner = scanner; | ||
| public CalcConsoleView() { | ||
| this.scanner = new Scanner(System.in); | ||
| } | ||
|
|
||
| @Override | ||
| public Command getCmd() { | ||
|
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. getCommand로 명시적으로 작성해주세요 |
||
| System.out.println(Messages.INPUT_GUIDE_MESSAGE); | ||
| System.out.print(Messages.INPUT_CHOICE_MESSAGE); | ||
| System.out.println(Messages.INPUT_GUIDE_MESSAGE.getMessage()); | ||
| System.out.print(Messages.INPUT_CHOICE_MESSAGE.getMessage()); | ||
|
|
||
| int choiceNum = this.scanner.nextInt(); | ||
| this.scanner.nextLine(); | ||
|
|
||
| Command command = Command.valueOf(choiceNum); | ||
| return command; | ||
| return Command.valueOf(choiceNum); | ||
| } | ||
|
|
||
| @Override | ||
|
|
@@ -51,13 +50,12 @@ public void showRecord(List<CalcResultRecordModel> calcResultRecordModelList) { | |
| private String calcRecordToFormattedStr(CalcResultRecordModel calcRecord) { | ||
| String expression = calcRecord.getExpression(); | ||
| double calcResult = calcRecord.getCalcResult(); | ||
| String formattedStr = expression + " = " + calcResult; | ||
| return formattedStr; | ||
| return expression + " = " + calcResult; | ||
| } | ||
|
|
||
| @Override | ||
| public void showExitMessage() { | ||
| System.out.println(Messages.EXIT_MESSAGE); | ||
| System.out.println(Messages.EXIT_MESSAGE.getMessage()); | ||
| } | ||
|
|
||
| } | ||
This file was deleted.
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.
DependencyInjectionContainer라는 네이밍은 너무 스프링 기술에 치중되어 있는 느낌이 드는데요,
실제로 스프링의 기술을 구현해서 사용하는 것이 아니라면, 다른 이름이 좋아보여요