BuNa_
IT Story
BuNa_
전체 방문자
오늘
어제
  • 분류 전체보기 (117)
    • CS (14)
      • 운영체제 (8)
      • 네트워크 (0)
      • Design Pattern (1)
      • OOP (4)
    • 대외활동 (24)
      • 우아한테크코스 (14)
      • DND 동아리 (4)
      • UMC 동아리 (5)
      • 해커톤 (1)
    • Android (29)
      • MVVM (2)
      • 스터디 (11)
      • Compose (3)
      • Unit Test (1)
    • Project (5)
      • 어따세워 (5)
      • DnD 과외 서비스 (0)
    • Programming (11)
      • Kotlin (4)
      • 파이썬 (7)
    • Git (1)
    • 인공지능 (22)
    • 백준 (8)
    • 기타 (3)
      • IntelliJ (1)
      • 일상 (0)

블로그 메뉴

  • 홈

공지사항

인기 글

태그

  • Compose
  • 다이나믹 프로그래밍
  • 우아한테크코스
  • 우테코
  • 객체지향 생활체조
  • 딥러닝
  • 백준
  • 어따세워
  • MVVM
  • 컴공선배
  • k-means++
  • 인공지능
  • 우테코 프리코스
  • 외부 단편화
  • Ai
  • External fragmentation
  • 안드로이드
  • Android
  • K-means
  • 인공지능 분류
  • 파이썬
  • UMC
  • 선형회귀
  • 셀레니움
  • Baekjoon
  • 우테코 5기
  • ViewModel
  • 운영체제
  • RecyclerView
  • 원시값 포장

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
BuNa_

IT Story

[Programming] 원시값과 컬렉션을 포장해야 하는 이유 - 래퍼 클래스, 일급 컬렉션(Wrapper class, First-class Collection)
CS/OOP

[Programming] 원시값과 컬렉션을 포장해야 하는 이유 - 래퍼 클래스, 일급 컬렉션(Wrapper class, First-class Collection)

2023. 2. 17. 14:31

해당 포스팅은 Kotlin 언어를 기반으로 작성하였습니다.

 

 

모든 원시값과 문자열을 포장하자

 

우선, 모든 원시값과 문자열을 포장하자는 이야기에 대해 살펴보겠습니다.

Lotto와 관련된 프로그램을 작성한다면, 원시값을 아래와 같은 코드로 검증해 줄 수 있습니다.

 

val lottoNumber: Int = 45

class Lotto(lottoNumbers: List<Int>) : List<LottoNumber> by lottoNumbers {
    init {
        lottoNumbers.forEach { validateLottoNumber(it) }
        validateLottoSize(lottoNumbers)
    }

    fun validateLottoNumber(lottoNumber: Int) {
        require(lottoNumber in MIN_LOTTO_NUMBER..MAX_LOTTO_NUMBER) { "Error! 로또 번호의 범위는 1부터 45입니다." }
    }

    fun validateLottoSize(lottoNumbers: List<LottoNumber>) {
        require(lottoNumber.size == LOTTO_SIZE) { "Error! 로또 번호는 6개여야 합니다." }
    }

    companion object {
        private const val LOTTO_SIZE = 6
        private const val MIN_LOTTO_NUMBER = 1
        private const val MAX_LOTTO_NUMBER = 45
    }
}

로또 번호는 1에서 45 사이의 범위에 속하기 때문에, 이를 벗어나는 숫자가 인자로 들어오면 IllegalArgumentException이 발생합니다.

값에 대한 검증도 해주고 있는데, 위 코드는 문제가 없는 것 아닐까요?

 

 

만약, 로또의 번호를 해당 Lotto 클래스가 아닌 다른 곳에서도 사용해야 한다면 매번 값의 범위를 검증해주어야 하는 문제가 발생합니다.

또한, 여기에서는 예시로 대중들이 흔히 알고 있는 Lotto라는 개념을 사용하지만, Lotto에 대한 개념이 없다고 가정했을 때 List의 Int가 의미하는 바가 무엇인지 파악하기에 다소 어려움이 존재합니다.

그 외에도, 깜빡하고 원시 타입인 로또 번호를 검증해주지 않았을 때 심각한 오류로 이어질 수 있었습니다.

 

또한, 로또의 번호를 검증하는 것이 과연 Lotto 클래스가 해야할 일인가 생각해 볼 필요가 있습니다.

현재 Lotto 클래스는 로또 번호 리스트의 개수 검증 + 로또 번호의 범위 검증이라는 2가지 일을 수행하므로, 관심사 분리가 제대로 되지 않았다고 할 수 있습니다.

 

 

val lottoNumber: Int = 45

// LottoNumber
value class LottoNumber(val number: Int) {
    init {
        validateLottoNumber(number)
    }

    fun validateLottoNumber(lottoNumber: Int) {
        require(lottoNumber in MIN_LOTTO_NUMBER..MAX_LOTTO_NUMBER) { "Error! 로또 번호의 범위는 1부터 45입니다." }
    }
}

// Lotto
class Lotto(lottoNumbers: List<LottoNumber>) : List<LottoNumber> by lottoNumbers {
    init {
        validateLottoSize(lottoNumbers)
    }

    fun validateLottoSize(lottoNumbers: List<LottoNumber>) {
        require(lottoNumber.size == LOTTO_SIZE) { "Error! 로또 번호는 6개여야 합니다." }
    }

    companion object {
        private const val LOTTO_SIZE = 6
        private const val MIN_LOTTO_NUMBER = 1
        private const val MAX_LOTTO_NUMBER = 45
    }
}

로또 번호를 의미하는 Primitive type인 Int형 프로퍼티를 LottoNumber라는 클래스로 감싸주었습니다.

이제 로또 번호라는 개념이 필요할 때마다, 필요한 곳에서 검증 코드를 작성할 필요가 없어졌습니다.

원시 타입을 감싸줌으로써,

 

1. 보일러 플레이트 코드를 줄일 수 있다. (= 사용하는 곳에서마다 반복적인 검증 코드가 필요 없음)

2. Lotto의 관심사를 분리할 수 있다.

3. 응집도를 높일 수 있다.

4. 비즈니스에 종속적인 래퍼 클래스

5. 변수가 의미하는 바를 명확히 파악할 수 있다.

 

위와 같은 효과를 얻을 수 있게 되었습니다.

또한, 위 코드에서는 LottoNumber가 감싸고 있는 number 프로퍼티가 불변이므로, 언제든 값의 Consistency를 보장할 수 있습니다.

 

 

 

저작자표시 비영리 변경금지 (새창열림)

'CS > OOP' 카테고리의 다른 글

객체지향 프로그래밍 - OOP 상속(Inheritance) 이란?  (1) 2022.11.01
객체지향 프로그래밍 - OOP 캡슐화(Encapsulation) 이란?  (1) 2022.10.20
객체지향 프로그래밍 - OOP 추상화(Abstraction) 이란?  (2) 2022.10.17
    'CS/OOP' 카테고리의 다른 글
    • 객체지향 프로그래밍 - OOP 상속(Inheritance) 이란?
    • 객체지향 프로그래밍 - OOP 캡슐화(Encapsulation) 이란?
    • 객체지향 프로그래밍 - OOP 추상화(Abstraction) 이란?
    BuNa_
    BuNa_
    안드로이드 개발자를 향해 달리고 있는 공대생입니다! 🧑 Android, Kotlin, Java, Python 등 학습하고 있는 내용과 프로젝트를 주로 업로드하고 있습니다. 지적과 조언은 언제나 환영입니다!😊 github : https://github.com/tmdgh1592

    티스토리툴바