: 컬렉션을 감싸는 래퍼 클래스
사람들이 블로그에 적어놓는 부분은 굉장히 정의가 심플하다. 정말 이걸로 끝일까?
비지니스에 종속적인 자료구조
“비지니스에 종속적이다” 이건 정확히 어떤 의미일까?
대부분의 글에서는 비지니스의 종속적이다라는 것을 검증로직을 예시로 들어서 설명하고 있다. 로또 번호를 무작위로 생성할 때 매번 로또번호가 올바르게 생성되었는지 검증하는 로직을 구현해야한다. 하지만 이를 래퍼클래스에 넣어서 사용하게 되면 개발자는 검증로직에 관해서 신경쓰지 않아도 생성자에서 자연스럽게 검증로직을 통해 유효성을 판단하게 된다. 즉 특정기능에 대해서 그와 연쇄적으로 해야하는 작업이 있을 때 래퍼클래스를 통해서 자연스럽게 처리할 수 있도록 해주는 특성이라는 것이다.
만약 일급 컬렉션이 아니라 상위 컬렉션으로 비지니스 구현한다고 생각해보자. 좀 더 구체적인 예시로 한 음식점에서 손님에게 해당 음식점의 메뉴들을 알려주는 경우라 하자. 그런데 손님은 토마토가 들어간 음식은 먹지 못한다. 그러면 가게 직원은 토마토를 제외한 음식을 손님에게 알려주어야 할것이다.
다음 코드를 생각해보자
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
// first case
class Food{
private String name;
public Food(String name){
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Food{" +
"name='" + name + '\\'' +
'}';
}
}
public class Restaurant{
private List<Food> menu;
public Restaurant(List<Food> menu){
validateNameCheck(menu);
this.menu = menu;
}
public List<Food> getAllFoodByCondition(Predicate<Food> predicate){
return menu.stream().filter(predicate).collect(Collectors.toList());
}
public void validateNameCheck(List<Food> list){
Optional<Food> cantSellFood = list.stream()
.filter(food -> food.getName().equals("discontinued food"))
.findAny();
if(cantSellFood.isPresent()){
throw new IllegalAccessException("error");
}
}
public static void main(String[] args){
List<Food> list = List.of(new Food("1"),new Food("2"),new Food("tomato"),new Food("3"));
Restaurant restaurant = new Restaurant(list);
System.out.println(restaurant
.getAllFoodByCondition(
food->!food.getName().equals("tomato"))
);
}
}
래퍼 클래스를 통해서 검증로직과 같은 종속적인 기능들을 한데 묶어서 일급컬렉션을 생성할 때에 자연스럽게 처리할 수 있게 코드가 만들어졌다. 이러한 점이 비지니스에 종속적이다라고 할 수 있다.
불변
식당 클래스를 다시 보도록하자
// first case
class Food{
private String name;
public Food(String name){
this.name = name;
}
public String getName() {
return name;
}
@Override
public String toString() {
return "Food{" +
"name='" + name + '\\'' +
'}';
}
}
public class Restaurant{
private List<Food> menu;
public Restaurant(List<Food> menu){
this.menu = menu;
}
public List<Food> getAllFoodByCondition(Predicate<Food> predicate){
return menu.stream().filter(predicate).collect(Collectors.toList());
}
public static void main(String[] args){
List<Food> list = List.of(new Food("1"),new Food("2"),new Food("tomato"),new Food("3"));
Restaurant restaurant = new Restaurant(list);
System.out.println(restaurant
.getAllFoodByCondition(
food->!food.getName().equals("tomato"))
);
}
}
식당 객체에 안에 있는 list가 변경될 수 있는지 확인해보아라.
변경될 수 없다는 것을 알 수 있다. 즉 불변하다.
이러한 불변한다는 점은 어떠한 요청이 들어오더라도 어느정도 일정한 퀄리티의 반환을 할 수 있게 만드는 안정성을 보장한다.
일급 컬렉션은 정보를 가지고 있는 컬랙션(데이터 컬랙션이라고 지칭하겠다.)이 래퍼 클래스에 들어가 있고 데이타 컬랙션에 대한 모든 메소드와 로직을 일급 컬랙션 안에서 관리를 하는 형태이다.
기존의 데이터 컬렉션이 여러개 있다면 그 컬렉션은 변수명으로 각각의 컬렉션을 구분할 수 밖에 없었다.