- 경주할 자동차들의 이름과 시도할 횟수를 입력받는다
- 유효성 검사와 예외 처리를 통해 올바른 입력만 허용한다. (예: 빈 입력, 중복된 이름, 자동차 이름 길이 등)
- 회차별로 자동차를 전진시킨 후 모든 회차가 끝난 후 우승한 자동차를 선정한다
- 회차별로 각 자동차 별로 0~9사이의 무작위 값을 생성한다.
- 무작위 값 생성 시 테스트를 위해 난수 생성기를 주입할 수 있도록 설계한다.
- 자동차 이동 여부 판정:
- 생성된 값이 4 이상이면 1칸 이동
- 생성된 값이 4 미만이면 변화 없음
- 회차별로 이동한 횟수만큼 "-"를 통해 이동 상태를 표시한다.
- 모든 회차가 끝난 후 가장 많이 이동한 자동차를 우승자로 선정한다.
- 우승자가 여러 명일 경우 쉼표(,)를 이용하여 구분
- 회차별로 각 자동차 별로 0~9사이의 무작위 값을 생성한다.
예외처리
IllegalArgumentException 이후 프로그램이 종료되도록 한다.
- 자동차 이름 입력 예외처리
- 자동차 이름 길이가 5자를 넘는 경우
- 빈 이름이 포함된 경우의 자동차 이름
- 같은 이름이 있는 경우 중복 처리
- 시도할 횟수 예외처리
- 숫자가 아닌 경우에 대한 처리
- 음수 또는 0일 경우에 대한 처리
- 빈 입력에 대한 처리
불변 클래스란?
- 그 인스턴스의 내부 값을 수정할 수 없는 클래스. 불변 인스턴스에 간직된 정보는 고정되어 객체가 파괴되 전까지 절대객체릐 달라지지 않음
- 객체의 상태를 변경하는 메서드(변경자)를 제공하지 않는다
- 클래스를 확장할 수 없도록 한다
- 모든 필드를 final로 선언한다
- 모든 필드를 private로 선언 한다
- 자신 외에는 내부의 가변 컴포넌트에 접근 할 수 없도록 한다
정적 팩터리를 사용한 불변 클래스
public final class Money {
private final int amount;
private final String currency;
// 생성자는 private → 외부에서 new로 만들 수 없음
private Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
// 정적 팩토리 메서드 (이름 있는 생성자 역할)
public static Money of(int amount, String currency) {
return new Money(amount, currency);
}
}TryCount를 불변 클래스로 사용
- 객체에서 변경되어서는 안되는 필드를 private, final 사용함
Cars는 일급 컬렉션으로 컬렉션 자체는 불변이지만 내부 요소는 가변
- Car의 경우는 움직여야 하기 때문
생성자가 하나뿐이기에 정적 팩터리메서드 사용 X
어떤 객체가 다른 객체를 포함해서 사용하는것(has-a 관계)
어떤 객체가 다른 객체의 기능 을 사용하고 싶을때 그 객체를 자신의 필드로 가지고 있다가 필요한 시점에 위임 하는 방식
상속**(inheritance)은 강력하지만, 잘못 사용하면 결합도(coupling)가 높아지고, 유연성 떨어지며, 오류를 유발가능**
부모클래스의 내부 구현에 강하게 의존하므로, 부모클래스가 바뀌면 자식클래스도 영향을 크게 받음
컴포지션(composition)은 필드로 다른 객체를 가지고 있으며, 그 객체에 기능을 위임함으로 더 유연하고 안정적 설계가 가능
- 자동차 전진 조건을 전략 패턴을 이용함
- Car가 직접 이동 조건을 판단하지 않고, 전략 객체에게 위임
- 필드로 가지고 있지않지만 이걸 컴포지션이라고 볼 수 있는지가 궁금
equals(Object obj)
- 두 객체가 논리적으로 같은지 비교
- Object 기본 구현은 단순히 주소비교 (==)
- 필요시 오버라이딩 해서 본인이 정의한 동등성 기준 넣어야함
hashCode()
- 객체를 식별하는 정수 해시값 반환
- HashSet, HashMap 같은 해시 기반 자료구조에서 필수
- equals()가 true라면 hashCode도 반드시 같아야 함
- 객체가 논리적으로 같은지 비교시 먼저 hashCode 비교후 equals 호출
- 자동차 이름이 같으면 안된다. 이것을 객체 단에서 처리
equals(Object obj) → 객체가 같다는 기준 정의 (역기서는 자동차의 이름)
hashCode() → Set<Car> uniqueCars = new HashSet<>(carList); 으로 중복검사 위해서