CH07 : 컬렉션
CHAPTER 7 : 컬렉션
범위 : 134p ~ 145p
단계 : 실전
제목 : 컬렉션 : 중첩을 제거하는 구조화 테크닉
내용 : 복잡한 리스트 처리를 정리하고 구조화하는 방법을 다룹니다.
INTRO
이 장에서는 배열과 List 같은 컬렉션을 따라다니는 악마를 소개하고, 이러한 악마를 퇴치하는 방법을 알아보겠습니다.
7.1 이미 존재하는 기능을 다시 구현하지 말기
코드 7.1은 for 반복문 내부에 if 조건문이 중첩되어 있어서 가독성이 좋지 않습니다.
boolean hasPrisonKey = false;
for (Item each: items) {
if (each.name.equals("감옥 열쇠")) {
hasPrisonKey = true;
break;
}
}
같은 기능을 다음과 같이 구현할 수 있습니다.
boolean hasPrisonKey = items.stream().anyMatch(
item -> items.name.equals("감옥 열쇠" )
);
anyMatch 메서드는 자바 표준 라이브러리에 있는 컬렉션 전용 메서드입니다. 조건을 만족하는 요소가 컬렉션 내부에 하나라도 포함되어있는 경우, true를 리턴한다. anyMatch를 사용하면 for 반복문과 if 조건문을 사용할 필요도 없이, 한 줄로 처리를 완료할 수 있습니다.
이처럼 anyMatch 메서드를 알고 있으면, 복잡한 로직을 직접 구현하지 않아도 됩니다. 반대로 모르면 로직을 직접 구현해야 하므로, 코드가 쓸데없이 복잡해집니다. 또한 구현 실수로 버그가 발생할 가능성도 있습니다.
표준 컬렉션 라이브러리에는 anyMatch 이외에도 편리하 메서드가 다양하게 준비되어있습니다. 따라서 for 반복문을 사용해 컬렉션을 직접 조작하고 있다면, 잠시 멈추고 표준 라이브러리에 같은 기능을 하는 메서드가 있는 확인해보세요.
7.2 반복 처리 내부의 조건 분기 중첩
컬렉션 내부에서 특정 조건을 만족시키는 요소에 대해서만 어떤 작업을 수행하고 싶은 경우가 있습니다.
for (Member member: members) {
if (0 < member.hitPoint) {
if(member.containsState(StateType.poison)) {
member.hitPoint -= 10;
if(member.hitPoint <= 0) {
member.hitPoint = 0;
member.addState(StateType.dead);
member.removeState(StateType.poison);
}
}
}
}
7.2.1 조기 컨티뉴로 조건 분기 중첩 제거하기
반복문 내부에 있는 조건 분기 중첩은 조기 리턴을 응용한 “조기 컨티뉴”로 해결할 수 있다.
- continue는 실행하고 있는 처리를 건너뛰고 다음 반복으로 넘어가는 제어 구문이다.
- “조건을 만족하지 않는 경우, continue로 다음 반복으로 넘어간다”라는 기법을 활용하는 것
for(Member member: members) {
if (member.hitPoint == 0) continue;
if (member.containState(StateType.poision)) continue;
member.hitPoint -= 10;
if (0 < member.hitPoint) continue;
member.hitPoint = 0;
member.addState(StateType.dead);
member.removeState(StateType.poison);
}
7.2.2 조기 브레이크로 중첩 제거하기
반복 처리 제어 구문에는 continue 이외에도 break가 있다.
- break는 처리를 중단하고 반복문 전체를 벗어나는 제어 구문이다. 조기 컨티뉴와 마찬가지로 조기 브레이크를 사용하면 로직이 단순해지는 경우가 많다.
7.3 응집도가 낮은 컬렉션 처리
컬렉션과 관련된 작업을 처리하는 코드가 여기저기에 구현될 가능성이 굉장히 높습니다. 응집도가 낮아진 것입니다. 그럼 어떻게 해야할까요 ?
7.3.1 컬렉션 처리를 캡슐화하기
컬렉션과 관련된 응집도가 낮아지는 문제는 일급 컬렉션 패턴을 사용해 해결할 수 있습니다.
- “일급 컬렉션(First Class Collection)”
- 컬렉션과 관련된 로직을 캡슐화하는 디자인 패턴이다.
클래스 설계 원리를 반영하면 일급 컬렉션은, 다음과 같은 요소로 구성된다고 할 수 있다.
- 컬렉션 자료형의 인스턴스 변수
- 컬렉션 자료형의 인스턴스 변수에 잘못된 값이 할당되지 않게 막고, 정상적으로 조작하는 메서드
7.3.2 외부로 전달할 때 컬렉션의 변경 막기
인스턴스 변수를 그대로 외부에 전달하면 클래스 외부에서 마음대로 멤버를 추가하고 제거해 버릴 수 있습니다.
외부로 전달할 때는 컬렉션의 요소를 변경하지 못하게 막아 두는 것이 좋습니다. 이 때는 “unmodifiableList()” 메서드를 사용합니다.
unmodifiableList() 로 리턴되는 컬렉션은 요소를 추가하거나 제거할 수 없습니다. 따라서 클래스 외부에서 망므대로 컬렉션을 조작하는 상황 자체를 방지할 수 있습니다.
Leave a comment