요약
일급 컬렉션은 컬렉션 객체를 감싸는 객체를 말한다.
일급 컬렉션은 객체를 만들 때 검증해야 할 로직을 모아 둘 수 있다.
일급 컬렉션은 해당 컬렉션이 행해야 할 책임을 모아 둘 수 있다.
불변성을 지키기 위해서는
setter 금지.
일급 컬렉션의 멤버 변수를 초기화할 때 가져온 인자를 새로운 주소값으로 재할당
getter 할 때 불변 객체 반환.
일급 컬렉션이란
일급 컬렉션은 컬렉션 객체를 감싸는 객체다.
일급 컬렉션은 멤버 변수로 감싸고자 하는 컬렉션만 갖는다.
1 2 3 4 5 6 7 8
| public class ParticipatedCars { private static final int START_POSITION = 0;
private final List<Car> cars;
}
|
일급 컬렉션의 강점
1. 일급 컬렉션은 해당 컬렉션의 검증 로직을 한 곳에 모을 수 있다.
예를 들어 자동차 경주에 참가할 자동차 리스트를 관리한다고 가정하자.
이때 참가할 자동차들의 이름은 중복되면 안된다.
일급 컬렉션을 활용하면 참가할 자동차를 생성할 때 다음 같이 검증할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ParticipatedCars { private static final int START_POSITION = 0;
private final List<Car> cars;
public ParticipatedCars(List<String> carNames) { checkCarNameDuplicated(carNames); this.cars = new ArrayList<>(); for (String carName : carNames) { cars.add(new Car(carName, START_POSITION)); } }
private static void checkCarNameDuplicated(List<String> carNames) { long count = carNames.stream().distinct().count(); if (count != carNames.size()) { throw new CarNameDuplicationException(); } }
}
|
이렇게 일급 컬렉션 객체의 생성자에 검증 로직을 넣어두면 참여중인 자동차 객체는 반드시 중복되지 않은 이름들을 가진다고 확신할 수 있다.
일급 컬렉션을 사용하지 않는다면 이런 검증 로직은 서비스 메서드로 처리하게 된다.
그러면 매번 참여중 인 자동차를 만들 때 마다 서비스 메서드를 호출해줘야 되는 번거로움이 생긴다.
2. 상태와 행동을 한 곳에서 관리 할 수 있다.
참여한 자동차들은 모두 레이싱을 시도하는 역할을 할 수 있다.
다음 같이 일급 컬렉션에 행동을 추가해서 관리할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| public class ParticipatedCars { private static final int START_POSITION = 0;
private final List<Car> cars;
public ParticipatedCars(List<String> carNames) { checkCarNameDuplicated(carNames); this.cars = new ArrayList<>(); for (String carName : carNames) { cars.add(new Car(carName, START_POSITION)); } }
public void executeCarRacing(RandomNumberGenerator randomNumberGenerator) { for (Car car : cars) { car.tryToMoveBy(randomNumberGenerator); } } }
|
일급 컬렉션을 통해 이 객체가 어떤 행동을 하는지도 한눈에 볼 수 있게됐다.
일급 컬렉션과 불변성
일급 컬렉션이 불변하다는 특징을 가졌다고 알려졌는데, 사실 그렇지 않을 수 있다는 포스트도 있다.
관련 포스트
불변성을 지키고 싶다면 다음 세가지를 지켜주자
- setter를 사용하지 않는다.
- 일급 컬렉션의 멤버 변수를 초기화할 때 가져온 인자를 새로운 주소값으로 재할당하자.
- getter를 할 때 불변한 콜렉션으로 반환하자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public class ParticipatedCars { private static final int START_POSITION = 0;
private final List<Car> cars;
public ParticipatedCars(List<String> carNames) { checkCarNameDuplicated(carNames); this.cars = new ArrayList<>(); for (String carName : carNames) { cars.add(new Car(carName, START_POSITION)); } }
public List<Car> getCars() { return Collections.unmodifiableList(this.cars); } }
|
여전히 궁금한 것들
- 왜 일급 컬렉션은