정의

컬렉션을 포장한 클래스로, 컬렉션과 관련된 로직을 해당 클래스에 담아 일급 객체*처럼 활용하는 방식
이 클래스는 컬렉션을 포함하고 있으며, 그 컬렉션을 유일한 인스턴스 변수로 가지는 객체임
- 컬렉션 자체와 컬렉션을 사용하는 로직을 일관되게 관리할 수 있어, 유지보수가 쉬운 코드를 작성할 수 있음
- 데이터 무결성, 불변성, 가독성 등 객체 지향의 장점을 활용하여 안정적이고 응집력 있는 코드를 만들기 좋음


* 일급 객체란?:
변수에 할당될 수 있고, 함수의 인수로 전달되거나, 함수의 반환값으로 사용할 수 있는 객체. 객체, 함수, 메서드 등이 일급 객체로 다뤄질 수 있음.  다른 데이터와 마찬가지로 프로그램에서 직접 다룰 수 있는 객체. 함수형 프로그래밍에서 중요하게 다뤄지는 개념

- 예: String message = "Hello, World!"; 에서 선언된 문자열 객체이자 변수 message는 일급 객체임."Hello, World!"는 단순한 문자열 데이터로 일급 객체가 아님. 데이터는 객체로 만들어질 수 있지만, 문자열 그 자체는 객체가 아님.
- 예: Runnable myRunnable = () -> System.out.println("Hello from Runnable"); 라는 람다 표현식에서 myRunnable도 일급 객체임. (함수나 메서드도 일급 객체일 수 있음.)

그럼 모든 객체는 일급 객체 아닌가?:
맞음. 근데 일급 객체 개념 자체가 프로그래밍 언어에서 객체를 어떻게 다루는지에 대한 거라서 아래 조건을 충족해야 함.
- 변수에 할당 가능해야 하고 / 함수의 인수로 전달 가능해야 하고 / 함수의 반환값으로 사용 가능해야 하고 / 데이터 구조(리스트, 맵 등)에 포함 가능해야 함
자바에서 모든 객체는 위에 해당하기 때문에 모든 객체는 일급 객체임.

예시

// StudentList: 일급 컬렉션으로, 학생 목록을 관리하면서 비즈니스 로직을 포함하고 있음
// 외부에서는 컬렉션 내부의 학생 목록을 변경할 수 없고, getStudents()를 통해서도 불변 리스트만 받을 수 있음

import java.util.Collections;
import java.util.List;
import java.util.Objects;

public class StudentList {
    // 컬렉션 하나만 인스턴스 변수로 가짐
    private final List<Student> students;

    public StudentList(List<Student> students) {
        this.students = Objects.requireNonNull(students);
    }

    // 컬렉션에 대한 직접 접근을 막고, 불변성을 보장
    public List<Student> getStudents() {
        return Collections.unmodifiableList(students);
    }

    // 비즈니스 로직 포함: 특정 학생이 있는지 확인
    public boolean containsStudent(Student student) {
        return students.contains(student);
    }

    // 비즈니스 로직 포함: 전체 학생 수
    public int count() {
        return students.size();
    }
}

 

// Order 클래스가 Item 객체들의 리스트를 관리하는 경우에,
// 리스트를 직접 사용하지 않고 일급 컬렉션인 ItemList를 사용하는 예시

import java.util.Collections;
import java.util.List;
import java.util.ArrayList;

class Item {
    private final String name;
    private final double price;

    public Item(String name, double price) {
        this.name = name;
        this.price = price;
    }

    public double getPrice() {
        return price;
    }
}

class ItemList {
    private final List<Item> items;

    public ItemList(List<Item> items) {
        this.items = new ArrayList<>(items);
    }

    // 컬렉션에 새로운 항목 추가 로직 포함
    public ItemList addItem(Item item) {
        List<Item> newItems = new ArrayList<>(this.items);
        newItems.add(item);
        return new ItemList(newItems);  // 불변성 유지
    }

    // 컬렉션에서 특정 비즈니스 로직 수행
    public double calculateTotalPrice() {
        return items.stream().mapToDouble(Item::getPrice).sum();
    }

    // 컬렉션의 보호된 접근
    public List<Item> getItems() {
        return Collections.unmodifiableList(items);
    }
}

public class Order {
    private final ItemList itemList;

    public Order(ItemList itemList) {
        this.itemList = itemList;
    }

    public double getTotalPrice() {
        return itemList.calculateTotalPrice();
    }
}

특징과 장점

1. 특징

1) 컬렉션 하나만 인스턴스 변수로 가짐
- 일급 컬렉션 클래스는 컬렉션을 관리하는 역할을 하지만, 인스턴스 변수로 컬렉션(List, Set 등) 하나만 가질 수 있음
- 다른 필드를 포함하지 않음으로써 컬렉션 관리에 집중

2) 불변성을 보장
- 상태를 변경하지 않고 새로운 객체를 반환함으로써 외부에서 컬렉션을 수정할 수 없도록 불변성을 보장
- 이를 통해 컬렉션에 불필요한 사이드 이펙트가 생기는 것을 방지

3) 비즈니스 로직 포함
- 컬렉션의 조회, 추가, 삭제 등 행위를 일급 컬렉션 내부에 구현하여, 컬렉션과 관련된 비즈니스 로직을 해당 클래스에 포함시킴
- 코드의 응집도가 높아지고, 컬렉션 사용과 관련된 중복 코드가 줄어듦
- 컬렉션 관련 비즈니스 로직을 캡슐화할 수 있음
  (예: 컬렉션에 요소 추가/제거 시 특정 조건을 검증하는 로직을 일급 컬렉션에 넣어 일관된 검증 수행)

4) 컬렉션 외부 직접 접근 차단
- 일급 컬렉션 내 메서드를 통해 접근하게 함으로써, 컬렉션에 직접 접근하는 것을 막아 캡슐화를 강화
- 컬렉션을 통해 발생할 수 있는 불필요한 결합도를 줄임


2. 장점

1) 데이터 변경 통제
- 컬렉션을 불변하게 관리할 수 있어 안전성이 높아짐

2) 응집도 증가
- 컬렉션과 관련된 비즈니스 로직을 한 곳에 모아 코드 가독성과 유지보수성 향상되고, 관리가 쉬워짐

3) 중복 코드 방지
- 컬렉션 사용과 관련된 중복 코드와 부작용이 줄어듦

4) 유효성 검증 및 제약 조건 적용
- 컬렉션에 데이터를 추가하거나 조회할 때 제약 조건을 쉽게 관리할 수 있음

비고

1. 정리해 보니 어렴풋이 알고 있던 정의가 말끔해졌다.

레퍼런스

1. 멘토링 강의, 도서관, 코드 예시의 경우 ChatGPT

 

'개발지식 조각 > Java' 카테고리의 다른 글

Thread 동기화  (0) 2024.12.03
도메인과 서비스  (1) 2024.11.29
Static (변수/메서드/클래스)  (0) 2024.10.31
클린 코드의 정의  (0) 2024.10.31
List, Set, Map, Queue  (0) 2024.10.31

+ Recent posts