Skip to content
Open

Prac #1915

Show file tree
Hide file tree
Changes from all commits
Commits
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
37 changes: 36 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,36 @@
# java-calculator-precourse
# java-calculator-precourse
___

## InputHandler
> 입력을 처리하는 클래스
### Reader
> 입력을 수행하는 클래스


## OuputHandler
> 출력을 처리하는 클래스
### Printer
> 출력을 수행하는 클래스


## NumberHandler
> 숫자를 관리하는 클래스
### Number
> 숫자를 구체화 한 클래스


## DelimiterHandler
> 구분자를 관리하는 클래스
### Delimiter
> 구분자를 구체화 한 클래스

## UserInputParser
> 사용자 입력을 파싱하는 클래스

## ServiceHandler
> 도메인 흐름을 담당하는 클래스

## Controller
> 입출력을 담당하고 ServiceHandler에게 도메인 로직을 요청하는 클래스


6 changes: 5 additions & 1 deletion src/main/java/calculator/Application.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
package calculator;

import calculator.controller.Controller;

public class Application {
public static void main(String[] args) {
// TODO: 프로그램 구현
Controller controller = new Controller();

controller.run();
}
}
15 changes: 15 additions & 0 deletions src/main/java/calculator/controller/Controller.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package calculator.controller;

import calculator.io.InputHandler;
import calculator.io.OutputHandler;
import calculator.service.domain.ServiceHandler;

public class Controller {
private final ServiceHandler serviceHandler = new ServiceHandler();

public void run() {
String userInupt = InputHandler.makeDelimiterNumberString();
String answer = serviceHandler.calculate(userInupt);
OutputHandler.printResult(answer);
}
}
10 changes: 10 additions & 0 deletions src/main/java/calculator/io/InputHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package calculator.io;

public class InputHandler {
public static String makeDelimiterNumberString() {
Printer.printMessage("덧셈할 문자열을 입력해 주세요.");
Printer.printNewLine();

return Reader.getString();
}
}
11 changes: 11 additions & 0 deletions src/main/java/calculator/io/OutputHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package calculator.io;

public class OutputHandler {
public static void printResult(String result) {
Printer.printMessageWithFormat("결과 : %s", makeResultLikeInteger(result));
}

private static String makeResultLikeInteger(String result) {
return result.replaceAll("\\.0$", "");
}
}
15 changes: 15 additions & 0 deletions src/main/java/calculator/io/Printer.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package calculator.io;

public class Printer {
public static void printMessage(String message) {
System.out.printf(message);
}

public static void printMessageWithFormat(String format, Object... args) {
System.out.printf(format, args);
}

public static void printNewLine() {
System.out.println();
}
}
9 changes: 9 additions & 0 deletions src/main/java/calculator/io/Reader.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package calculator.io;

import camp.nextstep.edu.missionutils.Console;

public class Reader {
public static String getString() {
return Console.readLine();
}
}
42 changes: 42 additions & 0 deletions src/main/java/calculator/service/domain/Delimiter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package calculator.service.domain;

public class Delimiter {
private final char delimiter;

public Delimiter(char delimiter) {
this.delimiter = delimiter;
}

/**
* 두 객체가 값이 동일한지 비교하도록 재정의.
*
* @param obj 비교 대상 객체
* @return 값이 동일하다면 true, 동일하지 않다면 false
*/
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true; // 같은 객체라면 값을 비교할 이유가 없기 때문에 바로 true를 반환하여 성능을 최적화한다.
}
if (obj == null || getClass() != obj.getClass()) {
return false; // Null Handling, Class Consistency
}
Delimiter other = (Delimiter) obj; // 다운캐스팅
return this.delimiter == other.delimiter; // 값 비교
}

public boolean hasSameValueAs(Delimiter other) {
if (this == other) {
return true; // 객체 동등성 체크
}
if (other == null) {
return false; // Null Handling
}
return this.delimiter == other.delimiter; // 값 비교
}

@Override
public int hashCode() {
return Character.hashCode(delimiter);
}
}
37 changes: 37 additions & 0 deletions src/main/java/calculator/service/domain/DelimiterHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package calculator.service.domain;

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

public class DelimiterHandler {
private final List<Delimiter> delimiterList;

public DelimiterHandler() {
delimiterList = new ArrayList<>(List.of(new Delimiter(','), new Delimiter(':')));
}

public void addDelimiter(char delimiter) {
if (!checkDuplicate(new Delimiter(delimiter))) {
delimiterList.add(new Delimiter(delimiter));
}
}

public boolean isValidDelimiter(char delimiter) {
Delimiter target = new Delimiter(delimiter);
for (Delimiter each : delimiterList) {
if (each.equals(target)) {
return true;
}
}
return false;
}

private boolean checkDuplicate(Delimiter newDelimiter) {
for (Delimiter each : delimiterList) {
if (each.hasSameValueAs(newDelimiter)) {
return true;
}
}
return false;
}
}
21 changes: 21 additions & 0 deletions src/main/java/calculator/service/domain/Number.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package calculator.service.domain;

import java.util.Arrays;
import java.util.Objects;

public class Number {
private final double numberValue;

public Number(double numberValue) {
this.numberValue = numberValue;
}

public Number add(Number other) {
return new Number(this.numberValue + other.numberValue);
}

@Override
public String toString() {
return String.valueOf(numberValue);
}
}
28 changes: 28 additions & 0 deletions src/main/java/calculator/service/domain/NumberHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package calculator.service.domain;

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

public class NumberHandler {
private final List<Number> numberList;

public NumberHandler() {
numberList = new ArrayList<>();
}

public void addNumber(Double number) {
if (number < 0) {
throw new IllegalArgumentException("음수는 입력할 수 없습니다.");
}
numberList.add(new Number(number));
}

public String calculatePlus() {
Number answer = new Number(0);
for (Number each : numberList) {
answer = answer.add(each);
}

return answer.toString();
}
}
28 changes: 28 additions & 0 deletions src/main/java/calculator/service/domain/ServiceHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package calculator.service.domain;

import java.util.List;

public class ServiceHandler {
private final NumberHandler numberHandler = new NumberHandler();
private final DelimiterHandler delimiterHandler = new DelimiterHandler();

public String calculate(String userInput) {
setDelimiterHandler(userInput);
setNumberHandler(userInput, delimiterHandler);
return numberHandler.calculatePlus();
}

private void setNumberHandler(String userInput, DelimiterHandler delimiterHandler) {
List<Double> numbers = UserInputParser.parseNumber(userInput, delimiterHandler);
for (Double each : numbers) {
numberHandler.addNumber(each);
}
}

private void setDelimiterHandler(String userInput) {
List<Character> customDelimiter = UserInputParser.parseCustomDelimiter(userInput);
for (Character each : customDelimiter) {
delimiterHandler.addDelimiter(each);
}
}
}
84 changes: 84 additions & 0 deletions src/main/java/calculator/service/domain/UserInputParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package calculator.service.domain;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class UserInputParser {
private static final int DELIMITER_INDEX = 2;

public static List<Character> parseCustomDelimiter(String userInput) {
List<Character> result = extractChars(userInput);

return result;
}

public static List<Double> parseNumber(String userInput, DelimiterHandler delimiterHandler) {
String userInputAfterParse = getUserInputAfterParse(userInput);
checkOnlyNumberAndDelimiter(userInputAfterParse, delimiterHandler);
List<Double> result = extractNumbers(userInputAfterParse, delimiterHandler);

return result;
}

private static void checkOnlyNumberAndDelimiter(String userInputAfterParse, DelimiterHandler delimiterHandler) {
for (Character each : userInputAfterParse.toCharArray()) {
if (!Character.isDigit(each) && !delimiterHandler.isValidDelimiter(each)) {
throw new IllegalArgumentException("형식에 맞지 않는 문자열을 입력했습니다.");
}
}
}

private static List<Double> extractNumbers(String userInputAfterParse, DelimiterHandler delimiterHandler) {
StringBuilder numberBuilder = new StringBuilder();
List<Double> numberList = new ArrayList<>();

for (Character each : userInputAfterParse.toCharArray()) {
if (delimiterHandler.isValidDelimiter(each)) {
if (numberBuilder.isEmpty()) {
continue;
}
numberList.add(Double.valueOf(numberBuilder.toString()));
numberBuilder.delete(0, numberBuilder.length());
continue;
}
numberBuilder.append(each);
}

if (!numberBuilder.isEmpty()) {
numberList.add(Double.valueOf(numberBuilder.toString()));
}
return numberList;
}

private static String getUserInputAfterParse(String userInput) {
String userInputAfterParse = removePatterns(userInput);

return userInputAfterParse;
}

private static String removePatterns(String userInput) {
Matcher matcher = createMatcher(userInput);

return matcher.replaceAll("");
}

private static List<Character> extractChars(String userInput) {
List<Character> result = new ArrayList<>();
Matcher matcher = createMatcher(userInput);

while (matcher.find()) {
result.add(matcher.group().charAt(DELIMITER_INDEX));
}

return result;
}

private static Matcher createMatcher(String userInput) {
Pattern pattern = Pattern.compile("//.\\\\n");

return pattern.matcher(userInput);
}

}