자동차 경주 구현에서는 우승자를 출력해야 하는 요구사항을 구현해야 했다. 따라서 자동차들 중 가장 멀리 간 위치를 구해주어야 한다. 이를 해결하기 위해 아래의 기능을 구현해야 했다.
1. 리스트를 Position을 기준으로 내림차순으로 정렬
2. 리스트 중 첫 번째 자동차의 Position 가져오기
자동차 리스트 -> Cars (일급 컬렉션)
자동차 객체를 리스트로 가지는 일급 컬렉션 (Cars)에서 위 문제들을 각 메소드로 분리하여 구현했다.
class Cars {
private final List<Car> cars = new ArrayList<Car>();
private Position getFirstPosition() {
// 가장 멀리간 자동차의 위치 구하기
}
}
getFirstPosition
가장 멀리간 자동차의 위치를 구하려면 해당 메소드는 두 가지 기능을 수행해야 한다.
1. 자동차 리스트를 위치(Position)을 기준으로 내림차순
2. 내림차순된 리스트에서 첫 번째 Car의 Position을 가져온다.
public class Car implements Comparable<Car> {
private final Name name;
private Position position;
@Override
public int compareTo(Car car) {
return position.compareTo(car.position);
}
}
class Position implements Comparable<Position> {
private final int position;
@Override
public int compareTo(Position otherPosition) {
return position - otherPosition.position;
}
}
나는 이 때 내림차순이기 때문에 Position에서 compareTo 메소드의 반환값을 구할 때 반대로 빼주었다.
position - otherPosition.position
: 오름차순
otherPosition.position - position
: 내림차순
반대로 빼주었을 때 발생할 수 있는 문제점
리뷰어 코니에게 이러한 피드백을 받았고 생각해보니 문제가 발생할 수 있었다. 일반적으로 Collections.sort(cars)
를 하면 오름차순을 예상할텐데 나는 요구사항에 맞춰 내림차순으로 바꿨기 때문이다. 따라서 위처럼 작성하는건 오히려 복잡해질 수 있다. 따라서 compareTo는 오름차순을 기준으로 구현하고 실제 비즈니스 로직에서 내림차순을 구현하면 된다.
private Position getFirstPosition() {
validateIsEmpty(); // 아무것도 없을 경우 예외 처리
Collections.sort(cars, Comparator.reverseOrder()); // 내림차순 정렬
// 정렬된 cars에서 첫번째 자동차의 위치를 구한다.
return cars.get(0).getPosition();
}
아무것도 없을 경우 예외가 발생할 수 있으므로 주의해야 한다.