diff --git a/src/main/java/coordinate/Coordinate.java b/src/main/java/coordinate/Coordinate.java new file mode 100644 index 00000000..2316f5d6 --- /dev/null +++ b/src/main/java/coordinate/Coordinate.java @@ -0,0 +1,5 @@ +package coordinate; + +public interface Coordinate { + void printSpecialCharacter(); +} diff --git a/src/main/java/coordinate/CoordinateFactory.java b/src/main/java/coordinate/CoordinateFactory.java new file mode 100644 index 00000000..ef6fd7fc --- /dev/null +++ b/src/main/java/coordinate/CoordinateFactory.java @@ -0,0 +1,15 @@ +package coordinate; + +public class CoordinateFactory { + public void checkStraight(String inputCoordinate) { + if (inputCoordinate.contains("-")) { + String[] split = inputCoordinate.replace("-", ",").split(","); + Coordinate coordinate = new Straight(split); + coordinate.printSpecialCharacter(); + return; + } + String[] split = inputCoordinate.split(","); + Coordinate coordinate = new NotStraight(split); + coordinate.printSpecialCharacter(); + } +} diff --git a/src/main/java/coordinate/Input.java b/src/main/java/coordinate/Input.java new file mode 100644 index 00000000..66deb73c --- /dev/null +++ b/src/main/java/coordinate/Input.java @@ -0,0 +1,18 @@ +package coordinate; + +import java.util.Scanner; + +public class Input { + public void inputCoordinate() throws IllegalArgumentException{ + System.out.println("좌표를 입력하세요."); + Scanner sc = new Scanner(System.in); + String line = sc.nextLine(); + validInput(line); + } + + private void validInput(String line) { + InputConverter inputConverter = new InputConverter(line); + CoordinateFactory factory = new CoordinateFactory(); + factory.checkStraight(inputConverter.deleteParentheses(line)); + } +} diff --git a/src/main/java/coordinate/InputConverter.java b/src/main/java/coordinate/InputConverter.java new file mode 100644 index 00000000..467cac80 --- /dev/null +++ b/src/main/java/coordinate/InputConverter.java @@ -0,0 +1,51 @@ +package coordinate; + +import java.util.regex.Pattern; + +public class InputConverter { + private static final Pattern COORDINATE_PATTERN = Pattern.compile("^\\([0-9][0-9]?+,+[0-9][0-9]?\\)+|^\\([0-9][0-9]?+,+[0-9][0-9]?\\)+-+\\([0-9][0-9]?+,[0-9][0-9]?\\)$"); + private final String inputCoordinate; + + public InputConverter(String inputCoordinate) { + if (isNotMatchPattern(inputCoordinate)) { + throw new IllegalArgumentException("좌표형식을 확인해주세요"); + } + this.inputCoordinate = deleteParentheses(inputCoordinate); + validateCoordinateRange(); + } + + public String deleteParentheses(String inputCoordinate) { + return inputCoordinate.replaceAll("[^0-9,-]*", ""); + } + + private boolean isNotMatchPattern(String inputCoordinate) { + return !COORDINATE_PATTERN.matcher(inputCoordinate).matches(); + } + + private void validateCoordinateRange() { + String[] tempLine; + if (this.inputCoordinate.contains("-")) { + tempLine = this.inputCoordinate.replace("-", ",").split(","); + checkRangeLoop(tempLine); + return; + } + tempLine = this.inputCoordinate.split(","); + checkRangeLoop(tempLine); + } + + private void checkRangeLoop(String[] tempLine) { + for (String input : tempLine) { + checkMaxRange(input); + } + } + + private void checkMaxRange(String input) { + if (isOverThanMaxRange(input)) { + throw new IllegalArgumentException("좌표는 24까지만 입력할수있습니다"); + } + } + + private boolean isOverThanMaxRange(String tempLine) { + return Integer.parseInt(tempLine) > 24; + } +} diff --git a/src/main/java/coordinate/Main.java b/src/main/java/coordinate/Main.java new file mode 100644 index 00000000..c06bf2ec --- /dev/null +++ b/src/main/java/coordinate/Main.java @@ -0,0 +1,17 @@ +package coordinate; + +public class Main { + public static void main(String[] args) { + Input input = new Input(); + + while (true) { + try { + input.inputCoordinate(); + } catch (IllegalArgumentException e) { + System.out.println(e.getMessage()); + continue; + } + break; + } + } +} diff --git a/src/main/java/coordinate/NotStraight.java b/src/main/java/coordinate/NotStraight.java new file mode 100644 index 00000000..fa01690a --- /dev/null +++ b/src/main/java/coordinate/NotStraight.java @@ -0,0 +1,16 @@ +package coordinate; + +public class NotStraight implements Coordinate { + private final double x1; + private final double y1; + + public NotStraight(String[] split) { + this.x1 = Double.parseDouble(split[0]); + this.y1 = Double.parseDouble(split[1]); + } + + @Override + public void printSpecialCharacter() { + System.out.println("좌표는(" + this.x1 +"," + this.y1 + ")입니다"); + } +} diff --git a/src/main/java/coordinate/README.md b/src/main/java/coordinate/README.md new file mode 100644 index 00000000..410d174f --- /dev/null +++ b/src/main/java/coordinate/README.md @@ -0,0 +1,19 @@ +- X,Y좌표는 모두 최대 24까지만 입력할수있다. (입력범위 초과시 에러문구출력후, 다시입력받음) +- 쉼표로 x,y값을 구분한다 +- 좌표값을 두 개 입력한 경우, 두 점을 있는 직선으로 가정한다. 좌표값과 좌표값 사이는 '-' 문자로 구분한다. +- 직선인 경우는 두 점 사이 거리를 계산해서 출력한다. +- 정상적인 좌표값을 입력한 경우, 해당 좌표에 특수문자를 표시한다. + + +Main: 예외발생시 계속입력받게한다(책임) Input(협력) + +Input: 좌표를 입력받는다(책임) InputConverter(협력), CoordinateFactory(협력) + +InputConverter: 좌표 입력받을때마다 생성자에서 좌표형식의 패턴,수의 범위를 검증한다. +패턴의 괄호를제거한다(책임) + +CoordinateFactory: 직선인지 아닌지 체크하고 좌표를 출력한다(책임) Coordinate(협력) + +Coordinate: 좌표의 개수에 따라 구현 클래스가 달라지는 인터페이스 +Straight: 좌표의개수가 2개인경우 좌표출력 + 제곱근값출력 +NotStraight: 좌표의개수가 1개인경우 좌표출력 \ No newline at end of file diff --git a/src/main/java/coordinate/Straight.java b/src/main/java/coordinate/Straight.java new file mode 100644 index 00000000..ab3ae53a --- /dev/null +++ b/src/main/java/coordinate/Straight.java @@ -0,0 +1,27 @@ +package coordinate; + +public class Straight implements Coordinate { + private final double x1; + private final double x2; + private final double y1; + private final double y2; + private final double sqrt; + + public Straight(String[] split) { + this.x1 = Double.parseDouble(split[0]); + this.y1 = Double.parseDouble(split[1]); + this.x2 = Double.parseDouble(split[2]); + this.y2 = Double.parseDouble(split[3]); + this.sqrt = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); + } + + public double getSqrt() { + return this.sqrt; + } + + @Override + public void printSpecialCharacter() { + System.out.println("좌표는(" + this.x1 +"," + this.y1 + ")-(" + this.x2 + "," + this.y2 + ")입니다." ); + System.out.println("두점 사이의 거리는" + this.sqrt); + } +} diff --git a/src/test/java/coordinate/InputTest.java b/src/test/java/coordinate/InputTest.java new file mode 100644 index 00000000..f6f4dce7 --- /dev/null +++ b/src/test/java/coordinate/InputTest.java @@ -0,0 +1,54 @@ +package coordinate; + +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.offset; +import static org.junit.jupiter.api.Assertions.*; + +class InputTest { + + @ParameterizedTest + @ValueSource(strings = {"(a,b)-(c,d)", "", " ", "가나다라", "가,나,다,라", "a", "10,10-20,40", "(10,30)-", "!@#$", "!,@,#,$", "(ㄱ,ㄴ)-(ㄷ,ㄹ)"}) + @DisplayName("좌표입력 패턴 실패테스트") + void testCoordinatePattern_False(String input) { + assertThrows(IllegalArgumentException.class, () -> { + new InputConverter(input); + }); + } + + @ParameterizedTest + @ValueSource(strings = {"(1,2)-(3,4)", "(10,20)", "(1,2)"}) + @DisplayName("좌표입력 패턴 성공테스트") + void testCoordinatePattern_Success(String input) { + assertDoesNotThrow(() -> new InputConverter(input)); + } + + + @ParameterizedTest + @ValueSource(strings = {"(-1,-2)","(25,26)", "(100,200)-(300,400)"}) + @DisplayName("좌표 범위 실패테스트") + void test(String input) { + assertThrows(IllegalArgumentException.class, () -> { + new InputConverter(input); + }); + } + + @ParameterizedTest + @ValueSource(strings = {"(10,20)", "(24,24)-(1,2)"}) + @DisplayName("좌표 범위 성공테스트") + void test2(String input) { + assertDoesNotThrow(() -> new InputConverter(input)); + } + + @Test + @DisplayName("제곱근 값 테스트") + void test3() { + String[] split = "10,20-3,9".replace("-", ",").split(","); + Straight straight = new Straight(split); + assertThat(straight.getSqrt()).isEqualTo(13.0384, offset(0.0001)); + } +} \ No newline at end of file