자바 일급 컬렉션 활용해보기

요약

일급 컬렉션은 컬렉션 객체를 감싸는 객체를 말한다.
일급 컬렉션은 객체를 만들 때 검증해야 할 로직을 모아 둘 수 있다.
일급 컬렉션은 해당 컬렉션이 행해야 할 책임을 모아 둘 수 있다.

불변성을 지키기 위해서는

  1. setter 금지.

  2. 일급 컬렉션의 멤버 변수를 초기화할 때 가져온 인자를 새로운 주소값으로 재할당

  3. 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);
}
}
}

일급 컬렉션을 통해 이 객체가 어떤 행동을 하는지도 한눈에 볼 수 있게됐다.

일급 컬렉션과 불변성

일급 컬렉션이 불변하다는 특징을 가졌다고 알려졌는데, 사실 그렇지 않을 수 있다는 포스트도 있다.

관련 포스트

불변성을 지키고 싶다면 다음 세가지를 지켜주자

  1. setter를 사용하지 않는다.
  2. 일급 컬렉션의 멤버 변수를 초기화할 때 가져온 인자를 새로운 주소값으로 재할당하자.
  3. 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); //<- getter할 때 불변된 리스트가 반환된다.
}
}

여전히 궁금한 것들

  1. 왜 일급 컬렉션은
Share