Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
16 changes: 16 additions & 0 deletions src/main/java/CoordinateApplication.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import coordinate.Figure;
import coordinate.FigureFactory;
import coordinate.Points;
import view.InputView;

public class CoordinateApplication {
private static InputView inputView;
private static FigureFactory figureFactory = new FigureFactory();
Copy link

@this-is-spear this-is-spear Aug 2, 2022

Choose a reason for hiding this comment

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

두 필드 전부 final 키워드를 붙여서 방어적인 코드로 설계하는 것이 좋아보입니다!


public static void main(String[] args) {
inputView = new InputView();
Copy link

@this-is-spear this-is-spear Aug 2, 2022

Choose a reason for hiding this comment

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

CoordinateApplication의 main을 실행할 때, InputView 인스턴스를 생성자로 주입하거나 미리 주입하는 건 어떨까요?

Points points = inputView.inputPoint();
Figure figure = figureFactory.getInstance(points);
figure.output();
}
}
22 changes: 22 additions & 0 deletions src/main/java/coordinate/AbstractFigure.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package coordinate;

public abstract class AbstractFigure implements Figure {
protected final Points points;

public AbstractFigure(Points points) {
if (points.size() != size()) {
throw new IllegalArgumentException(getName() + "의 길이는 " + size() + "이어야 합니다.");
}

this.points = points;
}

// protected Point getPoint(int index) {
// return points.getPoints().get(index);
// }
Copy link

@this-is-spear this-is-spear Aug 2, 2022

Choose a reason for hiding this comment

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

사용하지 않는 코드는 삭제하는 게 좋습니다 ☺️ 삭제하지 않고 방치하게 된다면 잊혀져서 관리가 잘 안되는 경우가 많더라구요 ㅜ

Copy link
Member Author

Choose a reason for hiding this comment

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

좋은 습관인 것 같습니다 ㅜ 앞으로 삭제하는 버릇을 들여야겠어요!


@Override
public Points getPoints() {
return points;
}
}
13 changes: 13 additions & 0 deletions src/main/java/coordinate/Figure.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package coordinate;

public interface Figure {
Points getPoints();

int size();

String getName();

double area();

void output();
}
5 changes: 5 additions & 0 deletions src/main/java/coordinate/FigureCreator.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package coordinate;

public interface FigureCreator {
Figure create(Points points);
}
24 changes: 24 additions & 0 deletions src/main/java/coordinate/FigureFactory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package coordinate;

import java.util.HashMap;
import java.util.Map;

public class FigureFactory {
public static final Map<Integer, FigureCreator> FIGURE_MAP = new HashMap<>();

static{
FIGURE_MAP.put(Line.LINE_POINT_SIZE, Line::new);
FIGURE_MAP.put(Triangle.TRIANGLE_POINT_SIZE, Triangle::new);
FIGURE_MAP.put(Rectangle.RECTANGLE_POINT_SIZE, Rectangle::new);
}

public Figure getInstance(Points points) {
Figure figure;
try{
figure = FIGURE_MAP.get(points.size()).create(points);
} catch (NullPointerException e){
throw new IllegalArgumentException("점의 개수는 2~4개여야 합니다.");
}
return figure;
}
}
29 changes: 29 additions & 0 deletions src/main/java/coordinate/Line.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package coordinate;

public class Line extends AbstractFigure{
public static final int LINE_POINT_SIZE = 2;

public Line(Points points) {
super(points);
}

@Override
public int size() {
return LINE_POINT_SIZE;
}

@Override
public String getName() {
return "선";
}

@Override
public double area() {
return points.get(0).getDistance(points.get(1));
}

@Override
public void output(){
System.out.printf("두 점 사이의 거리는 %f", area());
Copy link

@this-is-spear this-is-spear Aug 2, 2022

Choose a reason for hiding this comment

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

output 메서드를 String을 반환해서 OutputView에게 System.out.printf하도록 위임하는 건 어떨까요? String을 반환하게 구현한다면 테스트가 쉬워지고 콘솔에 출력하는 기능(OutputView)을 모으게 된다면 확장과 변경에 용이합니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

확실히 기능을 모으는게 유지보수에도 좋을 것 같네요! 감사합니다 :)

}
}
69 changes: 69 additions & 0 deletions src/main/java/coordinate/Point.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package coordinate;

import java.util.Objects;

public class Point {
private final int x;
private final int y;

private Point(int x, int y) {
this.x = x;
if (x < 0 || x > 24) {
throw new IllegalArgumentException();
}

Choose a reason for hiding this comment

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

유효성 검사를 실패하게 되면 인자를 주입할 필요가 없기 때문에 유효성 검사를 진행한 후 x에 값이 주입되어야 합니다.

Suggested change
this.x = x;
if (x < 0 || x > 24) {
throw new IllegalArgumentException();
}
if (x < 0 || x > 24) {
throw new IllegalArgumentException();
}
this.x = x;


this.y = y;
if (y < 0 || y > 24) {
throw new IllegalArgumentException();
}

Choose a reason for hiding this comment

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

이렇게 선언하는 방식이 가독성이 좋을 것 같은데 어떻게 생각하시나요? ☺️

Suggested change
this.x = x;
if (x < 0 || x > 24) {
throw new IllegalArgumentException();
}
this.y = y;
if (y < 0 || y > 24) {
throw new IllegalArgumentException();
}
if (x < 0 || x > 24) {
throw new IllegalArgumentException();
}
if (y < 0 || y > 24) {
throw new IllegalArgumentException();
}
this.x = x;
this.y = y;

}

public double getDistance(Point other) {
int xDifference = other.minusX(x);
int yDifference = other.minusY(y);
return Math.sqrt(square(xDifference) + square(yDifference));
}

private int minusX(int number) {
return this.x - number;
}

private int minusY(int number) {
return this.y - number;
}

private static int square(int number) {
return number * number;
}

public static Point of(int x, int y) {
return new Point(x, y);
}

public static Point ofCommaSeparator(String text) {
String[] values = text.split(",");
return new Point(Integer.parseInt(values[0]), Integer.parseInt(values[1]));
}

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x &&
y == point.y;
}

@Override
public int hashCode() {
return Objects.hash(x, y);
}

@Override
public String toString() {
return "Point{" +
"x=" + x +
", y=" + y +
'}';
}
}
24 changes: 24 additions & 0 deletions src/main/java/coordinate/Points.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package coordinate;

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

public class Points {
protected static final List<Point> points = new ArrayList<>();

public void addPoint(Point point) {
this.points.add(point);
}

public Point get(int index) {
return points.get(index);
}

public static List<Point> getPoints() {
return points;
}
Copy link

@this-is-spear this-is-spear Aug 2, 2022

Choose a reason for hiding this comment

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

방어적인 코드로 작성하지 않으면 내부 컬렉션의 값이 변경될 가능성이 있습니다. 만약 아무 조건없이 컬렉션의 참조값을 리턴하게 된다면 다른 인스턴스들이 내부 값이 변경된 상태로 로직을 수행할 수 있는 문제가 발생합니다.

  1. 리스트를 수정할 수 없도록 points 컬렉션은 읽기 전용 컬렉션으로 만들거나 방어적인 복사로 컬렉션을 새로 생성하는 방식으로 진행해야 합니다.
  2. 컬렉션에 담기는 객체들의 상태가 변경되지 않도록 불변 객체로 만들 필요가 있습니다. Point는 불변 객체이니 이 부분은 문제가 되진 않습니다.

Copy link
Member Author

Choose a reason for hiding this comment

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

불변객체의 중요성 꼭 기억하겠습니다!
그런데 getPoints가 사용되지 않는 메소드라 아예 제거해도 될거같습니다 ㅎㅎ


public int size(){
return this.points.size();
}
}
29 changes: 29 additions & 0 deletions src/main/java/coordinate/Rectangle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package coordinate;

public class Rectangle extends AbstractFigure {
public static final int RECTANGLE_POINT_SIZE = 4;

public Rectangle(Points points) {
super(points);
}

@Override
public int size() {
return RECTANGLE_POINT_SIZE;
}

@Override
public String getName() {
return "사각형";
}

@Override
public double area() {
return 0;
}

@Override
public void output() {
System.out.printf("사각형 넓이는 %d", area());
}
}
42 changes: 42 additions & 0 deletions src/main/java/coordinate/Triangle.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package coordinate;

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

public class Triangle extends AbstractFigure {
public static final int TRIANGLE_POINT_SIZE = 3;

public Triangle(Points points) {
super(points);
}

@Override
public int size() {
return TRIANGLE_POINT_SIZE;
}

@Override
public String getName() {
return "삼각형";
}

@Override
public double area() {
List<Double> distances = new ArrayList<>();
distances.add(points.get(0).getDistance(points.get(1)));
distances.add(points.get(1).getDistance(points.get(2)));
distances.add(points.get(2).getDistance(points.get(0)));

Choose a reason for hiding this comment

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

points를 바로 호출해서 내부 데이터를 가져오게 된다면 내부 값이 변경될 수 있는 문제가 발생할 수 있을 것 같아요. 그리고 추후 설계가 변경된다면 가장 먼저 수정되어야 할 부분이 될 수도 있을 것 같습니다. 내부 데이터를 바로 호출하는 방식이 아닌 추상 클래스에서 ponits 내부 값을 전달하는 함수를 선언하는건 어떨까요?

Double s = distances.stream().mapToDouble(i->i).sum() /2;

Choose a reason for hiding this comment

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

stream에서는 reduce() 함수도 제공하고 있습니다! 사용해보시는걸 추천드려요 ☺️

Double result = s;
for(Double d: distances){
result *= (s-d);
}

Choose a reason for hiding this comment

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

이 부분은 메서드로 선언하게 된다면 stream으로 모든 로직을 처리할 수 있어보입니다. 앞서 말씀드린 reduce도 가능해보이네요..!

Copy link
Member Author

Choose a reason for hiding this comment

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

stream 너무 어렵네요 ㅠㅠ 익숙해지기까지 많은 연습이 필요한 것 같습니다..


return Math.sqrt(result);
}

@Override
public void output() {
System.out.printf("삼각형 넓이는 %f", area());
}
}
34 changes: 34 additions & 0 deletions src/main/java/view/InputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package view;

import coordinate.Point;
import coordinate.Points;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;
import java.util.stream.Collectors;

public class InputView {
Scanner scanner = new Scanner(System.in);

Choose a reason for hiding this comment

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

InputView의 기능을 외부에서 접근 못하도록 접근 제어자와 final 키워드를 붙여 외부에서 호출 불가능하도록 설정할 필요가 있어 보여요!


public Points inputPoint(){
System.out.println("좌표를 입력하세요.");
String s = scanner.next();

Points points = new Points();
String[] strings = s.split("-");
for(String str: strings){
List<Integer> numbers = new ArrayList<>();
List<String> nums;
nums = Arrays.stream(str.split("\\(|,|\\)")).filter(t -> !t.isEmpty()).collect(Collectors.toList());

Choose a reason for hiding this comment

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

이렇게 한 번에 선언할 수 있어보입니다.

Suggested change
List<String> nums;
nums = Arrays.stream(str.split("\\(|,|\\)")).filter(t -> !t.isEmpty()).collect(Collectors.toList());
List<String> nums = Arrays.stream(str.split("\\(|,|\\)")).filter(t -> !t.isEmpty()).collect(Collectors.toList());

for(String n: nums){
numbers.add(Integer.valueOf(n));
}

Point point = Point.of(numbers.get(0), numbers.get(1));
points.addPoint(point);
}
return points;
}
}
4 changes: 4 additions & 0 deletions src/main/java/view/OutputView.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package view;

public class OutputView {
}