Conversation
- 기존에 Point를 각각 받던 것을 Point의 배열로 받도록 수정함
| public class Plate { | ||
| private final String[][] plate; | ||
|
|
||
| public Plate() { | ||
| this.plate = new String[26][26]; | ||
| for (int i = 0; i < plate.length; i++) { | ||
| String[] row = new String[27]; | ||
| Arrays.fill(row, " "); | ||
| plate[i] = row; | ||
| } | ||
|
|
||
| for (int i = 0; i < 24; i++) { | ||
| plate[i][1] = "|"; | ||
| if ((24 - i) % 2 == 0) { | ||
| plate[i][0] = " "; | ||
| } else { | ||
| plate[i][0] = String.format("%2d", 24 - i); | ||
| } | ||
| } | ||
|
|
||
| plate[24][0] = " "; | ||
| plate[24][1] = "+"; | ||
| plate[25][0] = " 0"; | ||
|
|
||
| for (int i = 2; i < 26; i++) { | ||
| plate[24][i] = "---"; | ||
| if ((24 - i) % 2 != 0) { | ||
| plate[25][i] = " "; | ||
| } else { | ||
| plate[25][i] = String.format(" %-2d", i - 1); | ||
| } | ||
| } | ||
|
|
||
| plate[24][1] = "+"; | ||
| plate[25][1] = " "; | ||
| } | ||
|
|
||
| public void drawPoints(Point[] points) { | ||
| for (Point point : points) { | ||
| plate[24 - point.getX()][point.getY() + 1] = " * "; | ||
| } | ||
| } | ||
|
|
||
| public void print() { | ||
| StringBuilder painter = new StringBuilder(); | ||
| for (String[] row : plate) { | ||
| for (String data : row) { | ||
| painter.append(data); | ||
| } | ||
| painter.append(System.lineSeparator()); | ||
| } | ||
|
|
||
| Terminal.out(painter.toString()); | ||
| } | ||
| } |
| public Line(Point point1, Point point2) { | ||
| this(new Point[]{point1, point2}); | ||
| } |
src/main/java/coordinate/Line.java
Outdated
| public Line(Point[] in) { | ||
| points = Arrays.copyOf(in, 2); | ||
| } |
There was a problem hiding this comment.
해당 생성자의 행위만 놓고 판단했을 때는 Point[] 배열의 길이가 2보다 더 길어도 그 후는 자르고 2의 길이를 가지는 Array를 해당 필드에 주입하는 것으로 보입니다.
따라서 이 Poin[] 배열은 외부에서 길이가 2임을 validate 한 후 이 생성자를 호출하고 있다고 판단되는데요!
해당 로직을 보고 제가 가지고 있는 고민을 공유해봅니다.
MVC 패턴에서 "인증, validate" 를 담당하는 쪽은 Controller 가 되야 하는것이 적절 해 보입니다. 그런데 이것은 즉 validate 라는 중요한 로직을 객체 스스로가 아닌 외부에 맡기는 형태가 되는 것이 아닌가? 하는 고민이 있습니다.
객체 스스로가 생성자의 인자를 validate 하면서, 외부에도 이 validation 에 대한 정보(혹은 예외) 를 적절히 전달 할 수 있는 방법은 없을까요? (외부에 공개된 녀석은 Controller 가 처리하는 식)
There was a problem hiding this comment.
음.. 객체 생성에 대해서 고민해보고 다음과 같이 정리하였습니다.
- 객체의 생성을 맡아서 다루는 책임에 따라 인자의 검증 로직이 위치해야 한다. 대표적으로 필요한 곳에서 생성자를 바로 호출하여 생성하는 경우와 객체 생성의 책임을 클래스에 위임하고 해당 클래스를 거쳐 생성하는 경우를 생각할 수 있다.
- 검증 로직은 안전을 위해 반복적으로 수행되거나 성능을 위해 반복되지 않게 할 수 있다. 개인 또는 조직이 추구하는 일반적인 방식에 따라 선택해야 한다.
따라서 다음 두 가지 방법을 생각할 수 있었습니다.
- 객체의 생성이 필요한 곳에서 생성자를 직접 호출하여 이루어진다. -> 생성자에 검증 로직이 위치
- 객체의 생성을 다른 클래스가 관장한다. -> 생성의 책임을 가진 클래스가 인자를 검증하고, 패키지 외부에서 생성자를 호출할 수 없도록 강제 한다.
다만 2번째 방법을 사용할 때, 방어적인 프로그래밍 방식을 선호한다면 객체 생성을 담당하는 클래스와 생성자 모두에 검증 로직을 위치 시킬 수 있고, 같은 로직이 반복적으로 수행되는 것을 가능한 피하고 싶다면 오직 객체 생성을 담당하는 클래스에만 검증 로직을 위치 시킬 수 있을 것 같습니다.
| } | ||
|
|
||
| int num = Integer.parseInt(in); | ||
| if (num < 1 || num > 24) { |
There was a problem hiding this comment.
원시값을 포장하면 어떨까요? 그렇다면 이 1과 24라는 숫자의 의미가 더 명확해 질 것 같습니다.
| public static GeometricElement getGeometricElement(Point[] points) { | ||
| if (points.length == 2) { | ||
| return new Line(points); | ||
| } | ||
|
|
||
| if (points.length == 4) { | ||
| return new Rectangle(points); | ||
| } | ||
|
|
||
| if (points.length == 3) { | ||
| return new Triangle(points); | ||
| } | ||
|
|
||
| throw new ArithmeticException("No Line or Shape"); | ||
| } |
There was a problem hiding this comment.
해당 로직은 Calculator 클래스의 관심사가 아닌 것 같습니다! 클래스를 이동해보면 어떨까요?
No description provided.