Open youngreal opened 2 years ago
- 실용성이 어느정도로 있는이야기인지 잘 모르겠지만 Comparable을 구현한 클래스를 확장해 값컴포넌트를 추가하신 경험이 있으신지 없으시다면 어떻게 생각하시는지 궁금합니다
설명해주신 내용의 경험은 없지만, 책의 내용을 인용하면 구체 클래스에서 새로운 값 컴포넌트를 추가하면 compareTo 규약을 지킬 방법이 없다
는 문구를 보니 꼭 필요하다면, 우회하는 방법을 사용해 아래 예제 코드처럼 구현하면 좋을 것 같습니다.
- 위의 내용에 이어 이 클래스에 원래 클래스의 인스턴스를 가리키는 필드를두자. 그런다음 내부 인스턴스를 반환하는'뷰 메서드를 제공한다 라는부분이 자꾸 물음표가 생깁니다 ㅠ 도와주세요
책에서 설명한 대로, 객체 지향적 추상화의 이점을 포기하고 '뷰' 메서드를 제공하면 아래와 같은 코드를 작성할 수 있습니다.
Point 클래스
class Point implements Comparable<Point> {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int compareTo(Point point) {
int result = Integer.compare(x, point.x);
if (result == 0) {
return Integer.compare(y, point.y);
}
return result;
}
}
NamedPoint 클래스
class NamedPoint implements Comparable<NamedPoint> {
// 원래 클래스의 인스턴스를 가르키는 필드
private Point point;
private String name;
public NamedPoint(Point point, String name) {
this.point = point;
this.name = name;
}
// 내부 인스턴스를 반환하는 '뷰' 메서드
public Point viewPoint() {
return point;
}
@Override
public int compareTo(NamedPoint namePoint) {
int result = point.compareTo(namePoint.point);
if (result == 0) {
return name.compareTo(namePoint.name);
}
return result;
}
}
이렇게 하면 NamedPoint 클래스에 원하는 compareTo 메서드를 새롭게 구현할 수 있게 되어 구체 클래스 Point에서 compareTo 일반 규약을 지킬 수 있게 됩니다.
Test 코드로 검증하면 아래와 같습니다.
class PointTest {
@DisplayName("compareTo의 일반 규약을 지킬 수 있다")
@Test
void test() {
Point point = new Point(1, 3);
NamedPoint namedPoint = new NamedPoint(new Point(1, 2), "food");
assertThat(point.compareTo(namedPoint.viewPoint())).isEqualTo(1);
assertThat(namedPoint.viewPoint().compareTo(point)).isEqualTo(-1);
}
}
실용성이 어느정도로 있는이야기인지 잘 모르겠지만 Comparable을 구현한 클래스를 확장해 값컴포넌트를 추가하신 경험이 있으신지 없으시다면 어떻게 생각하시는지 궁금합니다
위의 내용에 이어
이 클래스에 원래 클래스의 인스턴스를 가리키는 필드를두자. 그런다음 내부 인스턴스를 반환하는'뷰 메서드를 제공한다
라는부분이 자꾸 물음표가 생깁니다 ㅠ 도와주세요