Java

일급 컬렉션

민철킹 2021. 8. 25. 15:25

First Class Collection, 일급 컬렉션이란 무엇일까?

 

CollectionWrapping 하면서, 그 외의 다른 멤버 변수가 없는 상태를 일급 컬렉션이라고한다.

 

이는 두 그룹을 같은 묶거나 그룹의 각 원소에 규칙을 적용하는 동작을 처리할 수 있다.

 

각설하고 일급 컬렉션을 예제 코드로 만들어보고 왜 일급 컬렉션을 사용해야하는지를 알아보자.

 

List<Car> cars = new ArrayList<>();

Car 객체 인스턴스를 담는 cars라는 List를 생각해보자.

 

이를 일급 컬렉션으로 한번 감싸서 사용하면 아래와 같이 만들 수 있다.

public class Cars {

    private final List<Car> cars;
    public Cars(List<Car> cars) {
    	this.cars = cars;
    }
}

이렇게 사용할 때의 장점은 무엇일까?


1. 비즈니스에 종속적인 자료구조

 

일급 컬렉션을 사용하지 않을 때 만약 검증 로직과 같은 비지니스 로직이 필요하다면, 서비스 로직에서 그 일을 수행해야하고 이는 단일 책임 원칙을 위배하게된다.

public class CarService {

	public void createCar() {
    	List<Car> cars = createCars(); // 자동차 생성
        validateSize(cars); // 지정된 수만큼만 생성되야하는 검증 로직
    }
}

이는 자동차들을 만드는 모든 곳에서 검증 로직이 필요하게 된다. 이를 일급 컬렉션을 사용해 재정의한다면

 

public class Cars {
	
    private static final int CARS_SIZE = 3;
    
    private final List<Car> cars;
    
    public Cars(List<Car> cars) {
    	validateSize(cars);
        this.cars = cars;
    }
    
    private void validateSize(List<Car> cars) {
    	if(cars.size() != CARS_SIZE) {
        	throw new IllegalArgumentException("자동차는 3개만 존재해야해요!");
        }
    }
}

위와 같이 private하게 검증 로직을 숨길 수 있을 뿐만아니라 

public class CarService {

	public void createCar() {
    	Cars cars = new Cars(createCars());
    }
}

서비스는 단지 Cars를 생성하는 책임만 존재하므로 단일 책임 원칙또한 준수하게된다.

 

2. 불변(Immutable)

 

이 부분은 나도 깊게 생각하지 못했던 부분이었다.

Java에서의 final을 사용하면 컬렉션을 불변하게 만들 수 있지 않을까?

절대 그렇지 않다. final은 불변을 만들어주는 것이 아닌 재할당을 금지한다.

 

fianl List<String> list = new ArrayList<>();

list.add("응 불변 아니야~");
list.add("ㅋㅋㅋ");

fianl 키워드를 붙혀도 값을 추가, 삭제하는 것을 막을 수 없다. 즉, 불변이 아니다.

 

fianl List<String> list = new ArrayList<>();

list = new ArrayList<>(); // ==> 컴파일 에러

이렇게 재할당을 하려할 때 컴파일 에러가 발생한다.

 

public class Cars {

    private fianl List<Car> cars;
    
    public Cars(List<Car> cars) {
    	this.cars = cars;
    }
    
    public List<Car> getCars() {
    	return cars;
    }
}

일급 컬렉션을 사용하게되면 일급 컬렉션에는 생성자와 getCars만 존재하게 하여 List 에 접근자체가 불가하여 값을 변경/추가할 수 없는 불변 컬렉션으로 만들 수 있다.

 

3.  상태와 행위를 한곳에서!

이는 1번과 유사한데, 일급 컬렉션 내에 행위에 대한 특정 메소드를 넣게 되므로 상태와 행위를 한 곳에 관리하여 코드를 훨씬 더 편리하게 관리할 수 있다. 즉, Cars가 Car의 상태(ex: name, position)뿐 아니라 Car의 행위도 담게 된다는 의미.

 

4. 이름이 있는 컬렉션

List<Car> 국산차들 = createDomesticCars();
List<Car> 외제차들 = createForeignCars();

이렇게 변수명을 다르게하여 분리할 수 있지만 이는 변수명으로만 검색이 가능하므로 검색이 어렵고 명확한 표현이 불가능하다는 단점이 존재한다.

 

이를 일급 컬렉션을 사용하면 훨씬 더 명확하게 표현하고 검색이 용이해진다.

DomesticCars domesticCars = new DomesticCars(createDomesticCars());
ForeignCars foreignCars = new ForeignCars(createForeignCars());

 

반응형