학습 목적 : 멤버 테이블과 멤버가 가진 코인 정보 테이틀간 ERD 설계 및 개발 방향 고민 중에, 홈 화면에서 코인 조회 빈도가 많다보니, 코인정보는 캐싱하는 편이 나아보였다. Redis Cache 방향을 이야기하던 중, 일급 컬렉션이라는 말이 나왔고 처음 들어보는 워딩이다보니 공부를 해보고자 검색해보게 되었다.
정의 : 일급 컬렉션은 소트웍스 앤솔로지의 객체지향 생활체조 규칙 8. 일급 콜렉션 사용에서 언급되었다. 다른 객체와 동등한 지위를 갖는 컬렉션 객체를 의미한다. 즉, 컬렉션에 대한 처리를 하면서, 컬렉션 외 다른 멤버 변수가 없는 상태를 일급 컬렉션이라고 한다.
예시코드:
public class Student {
private List<String> subjects;
public Student(List<String> subjects) {
this.subjects = subjects;
}
public List<String> getSubjects() {
return subjects;
}
}
위 코드에서 Student 클래스에서 List<String> 타입의 subjects를 직접 다룬다. 이 경우 Student 클래스는 List 타입에 의존성을 갖게 되며, List의 구현이 변경될 경우 Student 클래스도 함께 변경되어야 하는 문제점을 가지고 있다.
public class Student {
private Subjects subjects;
public Student(Subjects subjects) {
this.subjects = subjects;
}
public Subjects getSubjects() {
return subjects;
}
}
public class Subjects {
private List<String> subjects;
public Subjects(List<String> subjects) {
this.subjects = subjects;
}
public void addSubject(String subject) {
subjects.add(subject);
}
public List<String> getSubjects() {
return new ArrayList<>(subjects);
}
}
위 코드는 Student 클래스에서 Subjects 클래스를 사용하도록 변경했다. Subjects 클래스는 List<String> 타입의 Subjects를 감싸고 있으며, Subject 개체를 추가하거나, 모든 Subject 객체를 가져올 수 있도록 메서드를 제공한다. 이렇게 할 경우 Student 클래스는 Subjects 클래스와만 의존성을 가지게 되고, 이전에 지닌 List 타입에 대한 의존성을 제거할 수 있다.
장점: 비지니스에 종속적인 자료구조, 컬렉션의 불변성 보장, 상태와 행위를 한 곳에서 관리할 수 있다는 점들을 들 수 있다.
* 비지니스에 종속적인 자료구조
ㄴ 비지니스 로직 : 사용자의 요구사항을 해결하기 위한 실질적인 코드
// 서비스 로직
public class StudentGroupService {
public void createStudentGroup() {
List<Student> studentGroup = List.of(
new Student(1, "John", 20, Department.MATH),
new Student(2, "Jane", 21, Department.PHYSICS),
new Student(3, "Max", 22, Department.MATH)
);
// 비즈니스 로직
// 동일한 Id가 있는지 검증
if (studentGroup.stream().map(Student::getId).distinct().count() != studentGroup.size()) {
throw new IllegalArgumentException("중복된 아이디가 있습니다.");
}
// 19살 이하 학생이 있는지 검증
if (studentGroup.stream().anyMatch(student -> student.getAge() <= 19)) {
throw new IllegalArgumentException("19살 이하의 학생이 있습니다.");
}
}
}
StudentGroup을 다른 곳에서도 활용할 경우, 검증 로직을 중복해서 작성해야한다는 단점이 있다.
public class StudentGroup {
private final List<Student> students;
public StudentGroup(List<Student> students) {
validateDuplicateId();
validateAgeLimit();
this.students = students;
}
private void validateDuplicateId() {
if (students.stream().map(Student::getId).distinct().count() != students.size()) {
throw new IllegalArgumentException("Duplicate Id exists");
}
}
private void validateAgeLimit() {
if (students.stream().anyMatch(student -> student.getAge() < 19)) {
throw new IllegalArgumentException("Age should be greater than 19");
}
}
}
StudentGroup이라는 일급 컬렉션을 만들고, 멤버 변수로 List를 두었다. 위처럼 작성하면, 검증 로직이 필요하다는 것도 알 수 있고, 중복되는 코드들도 최소화시킬 수 있다.
* 컬렉션의 불변성 보장
일급 컬렉션은 내부 상태가 변경되지 않기 때문에 다른 곳에서 변경을 시도할 수 없다. 불변성을 굳이굳이 지킬 필요는 없지만 프로그램의 안정성이나 예측 가능성을 높이기 위해선 필요해보인다.
ㄴ 생성자 함수에서 인자로 들어온 값을 this. 에 대입하는게 아닌 new ArrayList<>(args); 를 this.에 대입한다.
ㄴ 더하여 getter함수에서도 멤버변수를 리턴하는게 아닌 Collections.unmodifiableList(args);로 수정불가능한 상태로 리턴한다.
public class Order {
private final OrderItems items;
public Order(OrderItems items) {
this.items = items;
}
public OrderItems getItems() {
return items;
}
}
public class OrderItems {
private final List<String> items;
public OrderItems(List<String> items) {
if (items == null) {
throw new IllegalArgumentException("Items cannot be null.");
}
this.items = Collections.unmodifiableList(new ArrayList<>(items));
}
public List<String> getItems() {
return items;
}
}
* 상태와 행위를 한 곳에서 관리
일급 컬렉션의 장점은 상태와 행위를 한 곳에서 관리할 수 있다는 점이다.
https://dkswnkk.tistory.com/696
일급 컬렉션(First-Class Collection)이란?
일급 컬렉션(First-Class Collection)이란? Java에서 일급 컬렉션(First-Class Collection)은 다른 객체와 동등한 지위를 갖는 컬렉션 객체를 말합니다. 일급 컬렉션은 다음과 같은 특징을 가집니다. 컬렉션 객
dkswnkk.tistory.com
'Backend' 카테고리의 다른 글
| [FCM] CI/CD github secret에서 json 파일 만들 때 유의할 점 (0) | 2025.01.16 |
|---|---|
| [Spring Boot] 버전 3.3에서 변경된 WARN Serializing PageImpl instances as-is is not supported 해결법 (0) | 2025.01.12 |
| DDD 레이어드 아키텍처에 대한 고민 (0) | 2024.12.31 |
| Logback Rolling file appender 적용 (Docker volume mapping, Springboot ) (0) | 2024.12.30 |
| CICD 환경변수 문제 기록 (github actions, docker, ECR) (3) | 2024.12.29 |