[One Day One Question]
일급 컬렉션에 대해서 설명해 주세요
일급 컬렉션(First-class Collection)은 객체 지향 설계에서 컬렉션(리스트, 맵, 세트 등)을 다룰 때 사용하는 설계 패턴입니다. 단순히 컬렉션을 감싸는 클래스를 만드는 것처럼 보이지만, 이 패턴을 활용하면 설계의 명확성과 유지보수성을 크게 향상시킬 수 있습니다.
일급 컬렉션의 특징
- 단일 컬렉션만 포함
- 컬렉션 외에 다른 멤버 변수를 가지지 않습니다.
- 해당 클래스를 통해 컬렉션에 대한 작업을 수행합니다.
public class Members { private final List<Member> members; // 단일 컬렉션 public Members(List<Member> members) { this.members = new ArrayList<>(members); } }
- 불변성(Immutable)
- 컬렉션 내부 데이터를 직접 수정하지 못하도록 보장합니다.
- 데이터를 변경할 때는 새로운 일급 컬렉션을 반환합니다.
public Members add(Member member) { List<Member> newMembers = new ArrayList<>(members); newMembers.add(member); return new Members(newMembers); // 새로운 인스턴스 반환 }
Members teamMembers = new Members(List.of(new Member("Alice"))); Members updatedMembers = teamMembers.add(new Member("Bob")); System.out.println(teamMembers.toList().size()); // 출력: 1 (원본 변경 없음) System.out.println(updatedMembers.toList().size()); // 출력: 2 (새로운 컬렉션 생성)
- final 변수와 불변성의 차이점
더보기final은 불변이 아니라 재할당만 불가!
final List<String> name = new ArrayList<>(); name.add("park"); name.add("kim"); name.add("lee"); //데이터 변경, 추가 가능 name = new ArrayList<>(); //error!! 재할당만 불가
특징 final 변수불변성(Immutable) 기능 변수에 할당된 참조를 변경할 수 없게 함 객체의 내부 상태를 변경할 수 없게 함 초점 변수의 참조 자체에 초점 객체의 상태 관리에 초점 내부 데이터 변경 내부 데이터를 변경할 수 있음 (final은 참조만 고정) 내부 데이터를 변경할 수 없음 (완전히 불변) 적용 대상 변수나 필드에 적용 객체(클래스)의 설계와 구현 방식
- 비즈니스 로직 캡슐화
- 컬렉션에 대한 처리(검색, 추가, 삭제, 필터링 등)를 캡슐화하여 외부에서 직접 컬렉션에 접근하지 못하게 합니다.
public Members filter(Predicate<Member> condition) { List<Member> filtered = members.stream() .filter(condition) .collect(Collectors.toList()); return new Members(filtered); }
Members filtered = updatedMembers.filter(member -> member.getName().startsWith("A")); System.out.println(filtered.toList().size()); // "A"로 시작하는 멤버만 반환
- 컬렉션에 대한 처리(검색, 추가, 삭제, 필터링 등)를 캡슐화하여 외부에서 직접 컬렉션에 접근하지 못하게 합니다.
- 컬렉션 사용의 일관성 유지
- 일급 컬렉션을 통해 컬렉션 조작 방법을 통일할 수 있습니다.
public int size() { return members.size(); // 크기 확인 } public boolean contains(Member member) { return members.contains(member); // 특정 멤버 포함 여부 }
System.out.println(updatedMembers.size()); // 크기: 2 System.out.println(updatedMembers.contains(new Member("Alice"))); // 포함 여부: true
- 일급 컬렉션을 통해 컬렉션 조작 방법을 통일할 수 있습니다.
장점
1. 비즈니스 규칙 강제
컬렉션에 비즈니스 규칙을 추가하여 잘못된 데이터 입력을 방지할 수 있습니다.
public Members add(Member member) {
if (members.contains(member)) {
throw new IllegalArgumentException("중복된 멤버는 추가할 수 없습니다.");
}
List<Member> newMembers = new ArrayList<>(members);
newMembers.add(member);
return new Members(newMembers);
}
Members teamMembers = new Members(List.of(new Member("Alice")));
teamMembers = teamMembers.add(new Member("Bob")); // 정상 동작
teamMembers = teamMembers.add(new Member("Alice")); // 예외 발생
2. 코드 가독성과 유지보수성 향상
컬렉션 조작을 캡슐화하여 중복 코드를 제거하고 가독성을 높입니다.
public Members filterActiveMembers() {
return filter(Member::isActive); // 활성 상태인 멤버만 필터링
}
Members activeMembers = teamMembers.filterActiveMembers();
System.out.println(activeMembers.toList());
3. 객체 지향 설계 강화
컬렉션을 단순 데이터가 아니라 객체로 다루어 책임을 분리합니다.
public Members sortByName() {
List<Member> sorted = new ArrayList<>(members);
sorted.sort(Comparator.comparing(Member::getName));
return new Members(sorted);
}
Members sortedMembers = teamMembers.sortByName();
System.out.println(sortedMembers.toList());
4. 컬렉션 상태 관리
외부에서 컬렉션을 직접 변경하지 못하도록 상태를 안전하게 관리합니다.
public List<Member> toList() {
return Collections.unmodifiableList(members); // 수정 불가 리스트 반환
}
List<Member> membersList = teamMembers.toList();
membersList.add(new Member("Charlie")); // UnsupportedOperationException 발생
'cs > ODOQ' 카테고리의 다른 글
[ODOQ] 트랜잭션 격리수준 (0) | 2024.11.29 |
---|---|
[ODOQ] DB 인덱스(Index) (0) | 2024.11.28 |
[ODOQ] Checked Exception, Unchecked Exception (0) | 2024.11.26 |
[ODOQ] JPA의 N + 1 (0) | 2024.11.25 |
[ODOQ] TCP와 UDP의 차이점 (1) | 2024.11.25 |