일급 컬렉션과 값 객체(VO)컬렉션(Car)의 불변 보장상태와 행위를 한 곳에서 관리비즈니스에 종속적인 자료 구조마치며일급 컬렉션 vs 값객체record와 dtoToday in 프리코스
일급 컬렉션과 값 객체(VO)
이번 과제를 하면서 Car나 TryCount를 어떻게 관리할지 고민이 많았다. Car는 Cars라는 클래스로 감싸서 사용했는데 이가 일급 컬렉션과 관련이 있음을 알게 되었고 처음 들어보는 이 용어에 대해 학습했다.
그리고 TryCount 역시 일급 컬렉션으로 관리할 수 있을지 궁금했는데 글 끝에선 이는 값 객체와 관련됨을 알 수 있었다.
내가 좋아하는 이동욱님 글을 참고해 이번 과제에 적용해보며 생각해보았다.
소트웍스 앤솔로지 의 객체지향 생활체조 파트 내
규칙 8: 일급 콜렉션 사용 에 아래와 같은 내용이 나온다.콜렉션을 포함한 클래스는 반드시 다른 멤버 변수가 없어야 한다. 각 콜렉션은 그 자체로 포장돼 있으므로 이제 콜렉션과 관련된 동작은 근거지가 마련된셈이다. 필터가 이 새 클래스의 일부가 됨을 알 수 있다. 필터는 또한 스스로 함수 객체가 될 수 있다. 새 클래스는 두 그룹을 같이 묶는다든가 그룹의 각 원소에 규칙을 적용하는 등의 동작을 처리할 수 있다. 이는 인스턴스 변수에 대한 규칙의 확실한 확장이지만 그 자체를 위해서도 중요하다. 콜렉션은 실로 매우 유용한 원시 타입이다. 많은 동작이 있지만 후임 프로그래머나 유지보수 담당자에 의미적 의도나 단초는 거의 없다.
한 줄로 요약하자면,
콜렉션을 포장하면서 그 외 다른 멤버 변수가 없는 상태를 일급 컬렉션이라 일컫는다.이걸 이번 과제에 적용해보면 콜렉션이 Car고, Cars가 콜렉션을 포함한 클래스가 될 것이다. 코드로 보여주면 아래와 같다.
- 일급 컬렉션 사용
- 일급 콜렉션을 안 썼으면 아래와 같은 코드였을 것이다.
그렇다면 일급 콜렉션을 써서 얻는 이득이 뭘까? 코드로 보여주겠다.
컬렉션(Car)의 불변 보장
- 일급 컬렉션 사용 : 값 추가/변경 안됨
- 리스트 사용 : final로 재할당만 금지할 수 있을 뿐, 값 추가/변경이 가능함
상태와 행위를 한 곳에서 관리
- 일급 컬렉션 사용 : 값과 로직이 함께 존재함
- 리스트 사용 : 값과 로직이 흩어져 존재함
비즈니스에 종속적인 자료 구조
- 자동차 경주 게임의 조건 1
- 여러 대의 자동차가 존재
- 자동차들의 이름은 중복되지 않아야 함
- 일급 컬렉션 사용
→ 여러 대의 자동차로 이루어지고 자동차 이름이 중복되지 않는 자료구조 만들어 검증 로직을 정밀하게 관리
- 자동차 경주 게임의 조건 2
- 이동 시도 횟수(int)가 존재
- 이동 시도 횟수는 0 이상 이어야 함
- 값 객체(VO) 사용
→ 이동 시도 횟수로 이루어지고 그 값이 0 이상인 자료 구조 만들어 검증 로직 관리
마치며
Car와 TryCount가 다른 듯 비슷해서 두 개를 표현할 방법을 찾아나가기 위한 여정 속에 새로운 클래스들을 알게 되어 기쁘다.
처음엔 일급 컬렉션이란 용어만 알고서 미션에 적용해보다가, 값 객체(VO)라는 것도 자연스레 알게 되었다.
미션을 하며 느낀 둘의 공통점과 차이점을 간략히 정리해보며 글을 마무리하겠다.
다만,,, 이제 와서 든 생각은 내 로직에선 TryCount의 경우 값을 줄이고 늘리면 좋을 거 같아 VO로 쓰긴 적합하지 않을 거 같다.. 만일 본인의 로직에선 TryCount를 변경하지 않고 사용할 거라면 VO로 사용해도 좋지 않을까 싶다.
일급 컬렉션 vs 값객체
- 공통점
공통 |
값 변경 불가 (불변성) |
생성자에서 유효성 검증 (자가 유효성 검사) |
- 차이점
ㅤ | 일급 컬렉션 | 값 객체 |
의미 | 하나의 컬렉션만 멤버 변수로 가지는 클래스 | 변경 불가한 객체 |
목적 | 컬렉션 관련한 비즈니스 로직 한 곳에서 관리 | 특정 값을 표현해 값에 대한 로직과 유효성 캡슐화 |
구성 | 하나의 멤버 변수 + 컬렉션 다루는 메서드 | 하나 이상의 멤버 변수 + 값 다루는 메서드 |
특징 | ㅤ | 동등한 속성 가지면 객체 간 동등성 보장 |
record와 dto
이번 과제에서 Car의 이름과 위치를 쌍으로 전달할 일이 많았다. 이를 map으로 표현하는 방법도 있지만, 가독성이 현저히 떨어져 나만 알아보는 코드가 될 가능성이 있기에 이럴 땐 dto를 쓰는 게 좋다. dto를 만들고 놨더니 인텔리제이가 record로 바꿀 수 있다고 알려줬다.
record에 대해 처음 들어봤는데 dto와 비슷하되 가장 큰 차이점은 필드들이 불변으로 선언된단 점이다. dto는 급진적으로 봤을 땐 모든 필드를 public으로 둬도 괜찮다는 의견이 있을 정도로 변경에 취약하다. 하지만 record를 쓰면 데이터를 온전하게 전송할 수 있다.
Today in 프리코스
TIL 작성하기
몰입
구현 완성하기
테스트코드 짜기
1일차_둘러보기, 환경설정하기
Oct 19, 2023
DIARY_DEVELOP
2일차_컨벤션 정리하기
Oct 20, 2023
DIARY_DEVELOP
3일차_설계에 대해 고민하기
Oct 21, 2023
DIARY_DEVELOP
4,5일차_MVC 온전히 이해하기
Oct 22, 2023
DIARY_DEVELOP
6일차_설계를 코드로 구현하기
Oct 24, 2023
DIARY_DEVELOP
7일차_리팩토링과 마무리하기
Oct 25, 2023
DIARY_DEVELOP
8,9일차_코드 리뷰 통해 객체지향에 다가가기
Oct 27, 2023
DIARY_DEVELOP
10일차_지난 과제 돌아보며 객체지향 이해하기, 의존성과 설계의 관계 맛보기
Oct 28, 2023
DIARY_DEVELOP
11일차_객체지향을 미션 설계에 적용하기(with [책] 객체 지향의 사실과 오해)
Oct 29, 2023
DIARY_DEVELOP
12일차_기능 별로 구현하며 단위 테스트의 필요성 느끼기 (with [책]
자바와 JUnit을 활용한 실용주의 단위 테스트)Oct 30, 2023
DIARY_DEVELOP
13,14일차_일급 컬렉션과 레코드 적용해 리팩토링하기
Oct 31, 2023
DIARY_DEVELOP
15, 16일차_코드 리뷰를 통해 성장하기(1)_다른 사람의 코드 읽으면 배운 것 정리
Nov 2, 2023
DIARY_DEVELOP
17일차_코드 리뷰를 통해 성장하기(2)_내 코드 개선하며 배운 것 정리
Nov 4, 2023
DIARY_DEVELOP
18일차_내가 찾은 설계 방법 공유하기, 공유에 대해 고민하기
Nov 5, 2023
DIARY_DEVELOP
19일차_지난 과제 피드백 고려해 설계하기
Nov 6, 2023
DIARY_DEVELOP
20, 21일차_일단 돌아가는 코드를 만들기
Nov 7, 2023
DIARY_DEVELOP
22일차_현재 도움이 될 것 생각하기 (디자인패턴과 mvc2 과감히 패스)
Nov 9, 2023
DIARY_DEVELOP
23일차_코드리뷰하기 (feat. converter 파고들기)
Nov 10, 2023
DIARY_DEVELOP
24일차_기획을 문서화하기
Nov 11, 2023
DIARY_DEVELOP
25일차_설계하며 고민하기
Nov 12, 2023
DIARY_DEVELOP
26, 27일차_구현하며 고민하기
Nov 13, 2023
DIARY_DEVELOP
