HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🌚
[New] 우기팀
/
💊
7.2 컬렉션 캡슐화 하기
💊

7.2 컬렉션 캡슐화 하기

간단 요약 / 비고
작성일
May 24, 2022
작성자
기술 태그
객체지향
 

The Original Sin


객체 지향 개발자들은 캡슐화를 적극 권장하는데 컬렉션을 다룰 때는 곧잘 실수를 저지르곤 한다.
컬렉션 변수로의 접근을 캡슐화 하면서 게터가 컬렉션 자체(courses)를 반환 하도록 한다면, 그 컬렉션을 감싼 클래스 (Person)가 눈치채지 못하는 상태에서 컬렉션의 원소들이 바뀌어버릴 수 있다.
 

1. 컬렉션 변경자 메서드 제공

  • 모든 팀원이 원본 모듈(클래스) 밖에서는 컬렉션을 수정하지 않는 습관을 가지고 있다면 이런 메서드를 제공하는 것 만으로 충분
  • 하지만 실수 한 번이 굉장히 찾기 어려운 버그로 이어질 수 있으니 습관에 의존하는 방식은 바람직 하지 않다.
 

2. 내부 컬렉션을 직접 수정 하지 못하게 막기

a. 절대로 컬렉션 값을 반환하지 않기

  • 부가적인 코드가 너무 많아지는 단점
  • 컬렉션 연산들을 조합해 쓰기도 어려워 진다.
  • @See Also)
    • 일급 컬렉션 (First Class Collection)의 소개와 써야할 이유
 

b. 컬렉션을 읽기전용으로 제공

  • 방법 1 - 컬렉션의 읽기 전용 프락시를 반환
    • 읽는 연산은 그대로 전달, 쓰기는 예외를 던진다. (UnmodifiableCollection)
    • @)See Also
      • 월급쟁이 자유인 [Java] Unmodifiable Collection vs Immutable 차이점
  • 방법 2 - iterator나 열거형 객체를 기반으로 컬렉션을 조합하는 라이브러리
    • iterator에서 내부 컬력선을 수정 할 수 없게 함
  • 방법 3 - 컬렉션 게터를 제공하되 내부 컬렉션의 복제본을 반환 : 가장 널리 쓰이는 방식
    • 복제본을 수정해도 캡슐화된 원본 컬렉션에는 아무런 영향을 주지 않는다.
    • 컬력션을 수정하면 원본 데이터가 수정 될 것이라 기대한 프로그래머는 당황할 수 있지만 여러 코드베이스에서 많은 프로그래머가 널리 사용하는 방식이라 크게 문제되지 않음
    • 컬렉션이 상당히 크다면 성능문제가 발생할 수 있다.
 
⭐ 여기서 중요한 점은 코드베이스에서 일관성을 주는 것이다. 앞에 나온 방식 중에서 한 가지만 적용해서 컬렉션 접근 함수의 동작 방식을 통일해야 한다.
 
class Person{ private List<Course> cources = new ArrayList<>(); public List<Course> getCources{ return cources; } }
class Person{ private List<Course> cources = new ArrayList<>(); public List<Course> getCources{ return cources; } public addCource(Course course){ cources.add(course); } public removeCource(Course course){ cources.remove(course); } }
class Person{ private List<Course> cources = new ArrayList<>(); public addCource(Course course){ cources.add(course); } public removeCource(Course course){ cources.remove(course); } }