자동차 경주 결과를 나타내기 위해 toString()으로 결과를 반환하는 방법을 사용했다. Car에서 이름과 이동 거리를 :로 구분하여 보내면 view에서 :로 split하여 이름과 이동 거리를 구하고 사용하는 식으로 구현했었다.
public class Car {
...
@override
public String toString() {
return name.get() + ":" + position.toString(); // "알린:3"
}
}
---
public class View {
...
String[] carInformation = car.toString().split(":"); // "알린:3"
String name = carInformation[0]; // 알린
int position = Integer.parseInt(carInformation[1]); // 3
System.out.println(name + " : " + "-".repeat(Math.max(0, position)); // 알린 : ---
}
여기서는 도메인(Car)이 뷰의 세부 사항을 알고 있기 때문에 “비즈니스 로직과 UI 로직의 분리”를 만족하지 않는다. 또 toString()의 사용법이 적절하지 않다.
왜 toString()으로 출력 내용을 보내거나 정보를 보내면 안되는지 생각해보면서 정리해봤다.
이런 부분은 리뷰를 받으면서 이펙티브 자바의 Item 12를 참고하면 좋을 것 같다는 피드백을 받았다.
“이펙티브 자바의 Item 12”와 여러 블로그, 학습 로그를 보면서 toString()은 디버깅을 위해 사용하는 것 외에 사용은 하지 않는 것이 좋다고 생각하게 되었다. 그래서 toString()가 아닌 DTO를 이용하여 view에게 값을 전달하는 방법으로 수정하였다.
이전 코드는 내가 정한 규칙으로 반환한 toString()을 이용하여 나만 알 수 있는 방법으로 데이터를 가져왔던 것 같다. 다른 개발자가 이 코드를 본다면 쉽게 이해하기 어려울 수 있을 것 같다. toString()을 활용하는 방법을 잘못 이해했기 때문에 발생한 문제인 것 같다.
처음에 view에서 toString()으로 데이터를 가져온 이유는 강박적으로 getter를 쓰지 않기 위해서 였다. 그런데 조금 더 생각해보니 Car 객체의 이름과 이동 거리를 view에서 사용하게 되었기 때문에 getter를 써도 될 것 같다고 생각했다.
getter를 쓰지 말라는 이유는 getter로 반환된 값을 다른 메서드가 수정하거나 사용하는 로직을 처리하지 말라는 식으로 이해했다. 따라서 view에서 사용하기 위해서 getter를 하는 것은 허용이 되지않을까? 라고 생각했다.
Object의 기본 toString 메서드가 우리가 작성한 클래스에 적합한 문자열을 반환하는 경우는 거의 없습니다.
이 메서드는 PhoneNumber@adbbd처럼 단순히 클래스이름@16진수로표시한_해시코드를 반환합니다.
toString의 일반 규약에 따르면 '간결하고 사람이 읽기 쉬운 형태의 유익한 정보'를 반환해야 합니다.
toString의 규약은 '모든 하위 클래스에서 이 메서드를 재정의하라'고 합니다.
toString()의 특징은 다음과 같다.
이런 특징을 보면 어떤 로직에서 사용하기 보다는 더 쉬운 디버깅을 위해 사용하는 것이 올바른것같다. 그래서 항상 재정의하라는 것 같다.