소프트웨어 마에스트로 14기에 합격된 이후에 가장 먼저 하게 된 것은 백엔드 스터디에 참여한 것이었다.
본격적인 스터디를 하기전에 스터디원들과 함께 우테코 프리코스를 진행하고 코드리뷰를 진행하였다. 그 과정을 통해 일급 컬렉션이라는 것을 알게되었다.
생소한 용어였고, 처음 접해보았지만 일급 컬렉션을 사용하면 할수록 일급 컬렉션을 사용함으로써 얻을 수 있는 장점들에 대해서 느낄 수 있었다. 따라서, 해당 포스팅을 통해 일급 컬렉션에 대해서 정리하려고 한다.
먼저, 일급 컬렉션이란 Java Collection을 Wrapping 하면서, 그 외 다른 멤버 변수가 없는 상태를 말한다.
List<GameNumber> numbers = new ArrayList<>();
위의 코드를 아래와 같이 Wrapping 하는 것이다.
public class GameNumbers {
private final List<GameNumber> numbers;
private GameNumbers(List<GameNumber> numbers) {
this.numbers = new ArrayList<>(numbers);
}
}
여러 레퍼런스를 읽어보니, 공통적으로 일급 컬렉션의 장점을 아래와 같이 정리되어 있다.
- 비즈니스에 종속적인 자료구조
- Collection의 불변성을 보장
- 상태와 행위를 한 곳에서 관리
- 이름이 있는 컬렉션
이 중에서 실제 스터디를 하면서 느낀 일급 컬렉션의 장점은 아래 2가지이다.
나머지 장점에 대해서도 "그럴 수도 있겠구나"라고 느껴졌지만, 실제 스터디를 하면서 와닿지 않는 장점들이었다. 따라서 해당 포스팅에서는 아래 내용들에 대해서 정리하고 추후에 나머지 장점들에 대해서도 와닿는다면, 마저 정리하려고 한다.
- 비지니스에 종속적인 자료구조
- 상태와 행위를 한 곳에서 관리
1. 비지니스에 종속적인 자료구조
위 예시의 numbers에는 여러 조건들이 존재했다. 만약 일급 컬렉션을 사용하지 않고, 여러 조건들에 대해서 numbers를 검증한다면, 아래와 같이 실제 numbers를 생성하는 서비스 메서드에서 검증했을 것이다.
public class GameNumberService {
public void createGameNumbers() {
List<GameNumber> numbers = createNumbers();
validateXX(numbers);
validateXXXX(numbers);
}
...
}
위와 같이 서비스 메서드에서 numbers를 검증한다면, 아래의 문제점이 발생할 수 있다.
- numbers를 사용하는 모든 클래스에 해당 검증로직이 포함되어 중복 코드가 발생하고,
- 협업하는 상황이라면 실제 numbers가 어떤 검증 로직이 포함되는지 확인하는 번거로운 절차가 발생한다.
일급 컬렉션을 사용한다면, 검증로직을 일급 컬렉션에 작성하여 위의 문제점을 해결할 수 있다.
public class GameNumbers {
private final List<GameNumber> numbers;
private GameNumbers(List<GameNumber> numbers) {
validateXX(numbers);
validateXXXX(numbers);
this.numbers = new ArrayList<>(numbers);
}
...
}
numbers를 사용하는 외부에서는 검증 로직에 대해서 신경을 쓰지 않아도 되며, 중복 코드 또한 줄일 수 있다.
이를 통해 일급 컬렉션은 비즈니스에 종속적인 자료구조를 만들 수 있다.
3. 상태와 행위를 한 곳에서 관리
상태와 행위를 한 곳에서 관리하는 것은 객체지향 프로그래밍에서 중요하다.
사실 3번 장점과 1번 장점은 많이 상이한 내용은 아닌 것 같다. 1번 장점과 마찬가지로, 상태와 행위를 일급 컬렉션에서 관리함으로써 우리는 아래의 장점을 얻을 수 있다고 생각한다.
- 코드의 일관성과 유지보수성을 향상한다.
- 잘못된 상태나 행위를 방지할 수 있다.
public class GameNumbers {
private final List<GameNumber> numbers;
public GameNumbers(List<GameNumber> numbers) {
validateXX(numbers);
validateXXXX(numbers);
this.numbers = new ArrayList<>(numbers);
}
public Long getOddNumberCount() {
return ...
}
public Long getEvenNumberCount() {
return ...
}
}
getOddNumberCount()와 getEvenNumberCount() 외 다른 행위가 필요하다면, 여러 서비스 클래스에서 흩어지게 하지 않고, 일급 컬렉션에 작성할 수 있다.
이를 통해 일급 컬렉션은 상태와 행위를 한 곳에서 관리할 수 있게 한다.