내인생's 기록/도전

[워밍업 클럽 3기] BE클린코드&테스트코드 Day5

솔솔하네 2025. 3. 9. 14:11
반응형

🟡 오늘의 목표 진도


섹션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

https://www.inflearn.com/course/readable-code-%EC%9D%BD%EA%B8%B0%EC%A2%8B%EC%9D%80%EC%BD%94%EB%93%9C-%EC%9E%91%EC%84%B1%EC%82%AC%EA%B3%A0%EB%B2%95

 

Readable Code: 읽기 좋은 코드를 작성하는 사고법 강의 | 박우빈 - 인프런

박우빈 | , [사진]저 사람은 코드를 되게 잘 짜네. 어떻게 저런 코드를 작성하는 걸까? 🤔어떤 사람의 코드를 보고 '와 잘 짰다' 라고 느낄 때가 있습니다.우리가 '코드를 잘 짠다' 라고 표현하는

www.inflearn.com