글에 오류가 있으면 댓글로 피드백 부탁드립니다 :)
'일급 컬렉션' 뉘슈?
일급 컬렉션이란 먼저 다음과 같습니다.
- Collection을 포함한 클래스는 반드시 다른 멤버 변수가 없어야 한다.
- 부가설명 : Collection(List, Set ..)을 Wrapping한 변수가 있다면 그 외에 다른 멤버 변수는 없어야한다!
--> 오마이갓.. 이게 무슨 말일까요?
먼저 예시를 통해 일급 컬렉션을 이용한 프로그램을 보면서 이것의 장점과 사용 이유에 대해 더 알아보겠습니다.
예시(일급 컬렉션 적용 ver.)
예시에 앞서 먼저 프로그램 요구사항은 다음과 같습니다.
엔델 : 제이, 자동차 경주 게임 프로그램을 만들어주세요!
1. 자동차 경주를 할 사람은 'odo', 'kokodak', 'jay' 로 고정해주세요.
2. 저는 평등한게 좋으니 모든 라운드마다 자동차의 거리는 똑같이 1씩 증가시켜주세요.
3. 라운드의 수는 5로 고정입니다.
예상 결과 ==> 게임이 종료되면, 3명의 자동차의 거리가 5가 된다.
엔델의 요구에 따라 같이 자동차 경주 게임 프로그램을 간단하게 구현해야겠죠?
먼저 '자동차들'을 관리해야하므로, 제이는 다음과 같이 Car(자동차) 클래스를 만들었습니다.
그리고 다음과 같이 일급 컬렉션을 공부해서 Car 클래스를 List로 감싼 Cars 클래스를 만들었습니다.
1. Car 클래스
public class Car {
private final String name; // 자동차 이름
private int position; // 자동차의 위치
// 처음에 자동차 생성시에 자동차의 위치는 0이다.
public Car(final String name) {
validate(name);
this.name = name;
position = 0;
}
// 이름이 null값이 되면 에러 발생!
private void validate(final String name) {
if(name == null) {
throw new IllegalArgumentException("이름은 null값이면 안됩니다.");
}
}
// move() 메서드는 현재 자동차 위치 +1을 해주는 메서드
public void move() {
this.position++;
}
// 자동차의 이름을 반환한다.
public String getName() {
return name;
}
// 자동차의 현재 위치 반환한다
public int getPosition() {
return position;
}
}
2. Cars 클래스 (일급 컬렉션 사용)
import java.util.List;
public class Cars {
// 일급 컬렉션에서 멤버 변수는 하나만 있어야한다!
private final List<Car> cars;
public Cars(final List<Car> cars) {
this.cars = cars;
}
// moveAll()은 Cars가 관리하고 있는 자동차들의 위치를 모두 +1 시킨다.
public void moveAll() {
for (final Car car : cars) {
car.move();
}
}
}
이제 작동을 위해서 제이는 다음과 같이 컨트롤러를 만들었습니다.
3. CarController
import java.util.List;
public class CarController {
private static final int MOVE_TRY_COUNT = 5;
// 게임의 전반적인 흐름을 담당
public void startGame() {
Cars cars = new Cars(makeCars());
startRace(cars);
}
// 1. 게임에 필요한 자동차 세팅
private List<Car> makeCars() {
Car odo = new Car("odo");
Car kokodak = new Car("kokodak");
Car jay = new Car("jay");
List<Car> cars = List.of(odo, kokodak, jay);
return cars;
}
// 2. 게임을 5번 수행!
private void startRace(final Cars cars) {
for (int i = 0; i < MOVE_TRY_COUNT; i++) {
cars.moveAll();
}
}
}
이렇게 엔델이 만들어달라는 자동차 경주 게임을 일급 컬렉션을 이용해서 구현했습니다.
그렇다면, 이렇게 Cars를 통해서 List<Car>을 관리했을 때의 장점은 무엇일까요?
- 먼저 도메인의 상태 및 행위를 한 곳에서 관리할 수 있습니다.
// 컨트롤러에서 자동차들을 움직인다고 가정해보자!
// 1. 일급 컬렉션을 사용했을 때
cars.moveAll();
// 2. 일급 컬렉션을 사용하지 않았을 때
List<Car> cars = makeCars();
for (Car car : cars) {
car.move();
}
위에 1번 코드는, 일급 컬렉션을 사용했을 때입니다.
Cars 객체에 moveAll() 메서드를 통해 Cars가 관리하는 모든 Car 도메인의 움직임을 제어할 수 있습니다.
--> 이렇게 되면, Car 도메인은 자신의 행위에 충실 할 수 있겠죠? (이동)
위에 2번 코드는 일급 컬렉션을 사용하지 않았을 때입니다.
컨트롤러에서 먼저 List<Car>로 자동차를 관리해주는 List를 만들어줬습니다.
여기서 cars 리스트에 포함된 Car 객체를 움직이기 위해서 위와 같이 반복을 통해서 움직여줘야합니다.
따라서 일급 컬렉션은 모든 행위를 관리할 수 있다는 장점이 있습니다.
이와 더불어 일급 컬렉션의 장점을 자세히 알아봅시다!
- 일급 컬렉션을 사용하면, 모든 행위는 도메인이 알고 있다는 점에서 비즈니스 로직에 종속적이지 않다!
- 이말은 즉, 도메인은 자신의 행위에 집중할 수 있습니다.
- 추가 설명으로, 일급 컬렉션을 사용하지 않는다면 비즈니스 로직에서 모든 도메인과 그에 해당하는 코드를 알지 못한다면 문제가 발생할 수 있습니다.
- 일급 컬렉션을 사용하면, Collection의 불변을 보장한다.
- 이 말이 조금 어려울 수 있지만, 아래 사진을 통해서 자세히 알아봅시다!
위에서 사진에서 1번 예제를 본다면 일급 컬렉션을 사용했을 때, 새로운 Car 도메인을 추가할 수 없습니다.
그 이유는 일급 컬렉션에서 getter(), setter(), add() 같은 메서드를 만들지 않았기 때문입니다.
반면에, 2번 예제를 본다면 일급 컬렉션을 사용하지 않았을 때, 새로운 Car 도메인을 추가할 수 있습니다.
그 이유는 final로 선언을 해도, 재할당만 불가능하고 Collections 메서드로 내부 내용은 변경할 수 있기 때문입니다.
이제 이 말이 조금 이해 되시나요?!
이렇게 오늘은 일급 컬렉션에 대해 알아봤습니다!
'Develop > Java' 카테고리의 다른 글
[Java] 원시값 포장에 대해 알아보자 (2) | 2023.02.23 |
---|---|
[Java] 쉽다 쉬워! 전래동화를 통해 알아보는 단위 테스트 (0) | 2023.02.16 |
[Java] final 키워드에 대해 알아보자 (0) | 2023.02.13 |
[Java] AssertJ 문법과 간단한 예시 (예외처리 검증 추가) (0) | 2023.02.13 |
클린코드에 대해서 알아보자 (리팩토링) (0) | 2022.11.08 |