[워밍업 클럽 3기] BE클린코드&테스트코드 Day5
🟡 오늘의 목표 진도
섹션5. 객체 지향 적용하기
- Value Object
- 일급 컬렉션
- Enum의 특성과 활용
- 다형성 활용하기
- 숨겨져 있는 도메인 개념 도출하기
- 키워드 정리
🟠 공부 정리
1. 상속과 조합
✔ 상속보다 조합을 사용하기
✔ 부모와 자식의 결합도가 높아 수정이 어려움
✔ 조합과 인터페이스를 활용하는 것이 유연한 구조
2. VO vs Entity
✔ Value Object
- 도메인의 어떤 개념을 추상화하여 표현한 값 객체
- 값으로 취급하기 위해서, 불변성, 동등성, 유효성 검증 등을 보장해야 함
- 불변성 : final 필드, setter금지
- 동등성 : 서로 다른 인스턴스여도 내부의 값이 같으면 값은 값 객체로취급. equals() & hashCode() 재정의 필요
- 유효성 검증 : 객체가 생성되는 시점에 값에 대한 유효성을 보장하기
- 불변셩 : final 필드, setter금지
- 동등성 : 서로 다른 인스턴스여도 내부의 값이 같으면 값은 값 객체로취급. equals() & hashCode() 재정의 필요
- 유효성 검증 : 객체가 생성되는 시점에 값에 대한 유효성을 보장하기
✔ Entity
- 식별자(ex userId)가 존재함. 식별자가 아닌 필드의 값이 달라도, 식별자가 같으면 동등한 객체로 취급
- equals() & hashCode()도 식별자 필드만 가지고 재정의 할 수 있음
- 식별자가 같은데 식별자가 아닌 필드의 값이 서로 다른 두 인스턴스가 있다면, 같은 Entity가 시간이 지남에 따라 변화한 것으로 이해 할 수 있음
✔ VO vs Entity
- VO는 식별자 없이, 내부의 모든 값이 다 같아야 동등한 객체로 취급
3. 일급 컬렉션
✔ 일급 시민
- 다른 요소에게 사용 가능한 모든 연산을 지원하는 요소(변수로 할당 ok, 파라미터로 전달 ok, 함수의 결과로 반환 ok)
✔ 일급 컬렉션
- 컬렉션을 포장하면서, 컬렉션만을 유일하게 필드로 가지는 객체
- 컬렉션을 다른 객체와 동등한 레벨로 다루기 위함
- 단 하나의 컬렉션 필드만을 가짐
- 컬렉션을 추상화하며 의미를 담을 수 있고, 가공 로직의 보금자리가 생김
- 만약 getter로 컬렉션을 반환할 일이 생긴다면, 외부 조작을 피하기 위해 꼭 새로운 컬렉션으로 만들어서 반환 해주기
4. Enum의 특성과 활용
✔ Enum은 상수의 집합이며, 상수와 관련된 로직을 담을 수 있는 공간
✔ 특정 도메인 개념에 대해 그 종류와 기능을 명시적으로 표현해줄 수 있음
✔ 만약 변경이 정말 잦은 개념은, Enum 보다 DB로 관리하는 것이 나을 수 있음
5. 다형성 활용하기
변하는 것과 변하지 않는 것을 분리하여 추상화하고, OCP를 지키는 구조
// 반복적인 if문
// CellSnapshotStatus의 상태가 늘어나면 그만큼 if문의 코드도 늘어남
if(status == CellSnapshotStatus.EMPTY) {
return EMPTY_SIGN;
}
if(status == CellSnapshotStatus.FLAG) {
return FLAG_SIGN;
}
if(status == CellSnapshotStatus.LAND_MINE) {
return LAND_MINE_SIGN;
}
if(status == CellSnapshotStatus.UNCHECKED) {
return UNCHECKED_SIGN;
}
// 현재 if문을 보면
// 어떤 '조건'을 만족하면, 그 조건에 해당하는 '행위'를 수행의 반복
// - 변화하는 것 (구체)
// 조건 & 행위
// - 변하지 않는 것 (추상)
// 1. 조건을 만족하는가?
// 2. 행위를 수행한다.
6. 숨겨져 있는 도메인 개념 도출하기
✔ 도메인 지식은 만드는 것이 아니라 발견하는 것
✔ 객체 지향은 현실을 100% 반영하는 도구가 아니라, 흉내내는 것
✔ 설계할 때는 근시적, 거시적 관점에서 최대한 미래를 예측하고, 시간이 지나 만약 틀렸다는 것을 인지하면 언제든 돌아올 수 있도록 코드 를 만들어야 함(완벽한 설계는 없다!! 그 당시의 최선이 있을 뿐)
🔵 공부 후 나의 생각
지금까지 Enum을 사용할 때,
다른 사람이 보기 쉽게 하기 위해 각 값마다 주석을 달아 설명하는 방식으로 사용해왔다.
하지만 이번에 공부하면서 Enum 값에 설명(description) 필드를 추가하는 방법을 알게 되었다.
이 방법을 사용하면, Enum 자체에 의미를 내포할 수 있어 가독성이 좋아지고, 유지보수도 더 쉬워지는 것 같다.
예를 들어, 다음과 같이 description 필드를 추가하면 Enum 값에 대한 설명을 코드 내에서 쉽게 활용할 수 있다.
public enum UserAction {
OPEN("셀 열기"),
FLAG("깃발 꽂기"),
UNKNOWN("알 수 없음");
private final String description;
UserAction(String description) {
this.description = description;
}
}
또한, 이에 관해서 구글링해보니 Lombok 라이브러리를 활용하면 코드의 반복을 줄이는 방법도 있었다.
@RequiredArgsConstructor
public enum UserAction {
OPEN("셀 열기"),
FLAG("깃발 꽂기"),
UNKNOWN("알 수 없음");
private final String description;
}
이처럼 Lombok을 사용하면 코드를 단순화하면서도 가독성을 유지할 수 있다는 점도 새롭게 배운 부분이다.
앞으로는 주석 대신 Enum 필드를 적극적으로 활용해 더 명확하고 유지보수하기 쉬운 코드를 작성해야겠다고 느꼈다.
* 현재 인프런 워밍업 클럽에 참여하여 아래 강의 수강 중입니다.
https://www.inflearn.com/roadmaps/5699
클린 코드 & 테스트 코드 가이드 로드맵 로드맵 - 인프런
Spring, TDD 스킬을 학습할 수 있는 로드맵을 인프런에서 만나보세요.
www.inflearn.com
Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의 | 박우빈 - 인프런
박우빈 | , [사진]저 사람은 코드를 되게 잘 짜네. 어떻게 저런 코드를 작성하는 걸까? 🤔어떤 사람의 코드를 보고 '와 잘 짰다' 라고 느낄 때가 있습니다.우리가 '코드를 잘 짠다' 라고 표현하는
www.inflearn.com