Collection을 Wrapping하면서 그 외의 다른 멤버 변수가 없는 상태를 일급 컬렉션 정의한다!
Collection을 Wrapping?? 흠.. 영어라 좀 어려운데?
예시를 통해 알아가보자
public class Lotto {
private final List<Integer> numbers;
//멤버 변수는 단 하나이며, 추가되지 않는다는 전제조건!
public Lotto(List<Integer> numbers) {
validate(numbers);
this.numbers = numbers;
}
private void validate(List<Integer> numbers) {
..
}
}
위의 Lotto는 numbers 단 하나의 멤버 변수를 가지고 있다. 이것이 일급 컬렉션이다!
일급 컬렉션은 소트윅스 앤솔로지의 객체지향 생활체조 파트의 규칙 8에서 언급이 되었다고 합니다.
규칙 8: 일급 콜렉션 사용
…
콜렉션을 포함한 클래스는 반드시 다른 멤버 변수가 없어야 한다.
..
콜렉션은 실로 매우 유용한 원시 타입이다.
로또 구입 금액을 입력 받는다. 구입 금액은 1,000원 단위로 입력 받으며 1,000원으로 나누어 떨어지지 않는 경우 예외 처리한다.
라는 제시 조건을 살펴보자. 금액은 1,000원 단위다.
라는 조건이 제시되고 있다.
해당 조건들을, money를 저장하고 있는 서비스 객체에서 구현을 한다면 money를 가진 모든 장소에서 해당 금액에 대한 검증이 필요하다!
→ 일급 컬렉션 구조로, 특정 조건을 이미 포함한 새로운 자료구조를 생성해 해결하자!
public class Money {
private int money; //단 하나의 멤버
private Money(int money) {
this.money = money;
}
public static Money from(int money) {
validate(money); //구입 금액이 1,000으로 나누어떨어지는가?
..
}
public Lotto(List<LottoNumber> lotto) {
this.lotto = new ArrayList<>(lotto);
}
생성자로 받는 컬렉션값을 그대로 반환하는 기능은 만들지 않는다.
반환은 오직 가공된 값, 목적에 맞는 값만 반환한다!
일급 컬렉션은 값과 로직이 함께 존재하여 외부에서의 중복된 메서드의 생성과 같은 문제를 방지한다.
따라서 코드의 길이가 길어지고 중복 코드가 발생해 가독성이 떨어지는 문제를 개선한다.
즉, 일급 컬렉션을 생성하고 해당 메서드들을 일급 컬렉션 내에 만들어두고 외부에서는 호출을 하여 사용하도록 프로그래밍하면 상태와 행위를 한 곳에서 관리할 수 있다.
List<Integer> authLotto = createAuto();
List<Integer> manualLotto = createManual();
로또 발급에 자동방식과, 수동 발급 방식이 있다고 가정하자.
이 코드의 단점은 무엇일까?
같은 6개의 숫자로 구성된 로또이지만 둘의 발급 방식 등에는 차이가 있다.
AutoLotto autoLotto = new AutoLotto(createAuto());
ManualLotto manualLotto = new ManualLotto(createManual());
로 분리한다면 위의 두 문제를 해결할 수 있다!
출처
[**일급 컬렉션 (First Class Collection)의 소개와 써야할 이유]** (https://jojoldu.tistory.com/412)