본문 바로가기
Data Platform/Scala

case class와 companion object 그리고 case object

by 태하팍 2025. 3. 31.
반응형

아직 소스를 제대로 보진 못했지만
case class와 companion object이 친구들이 매우 핵심적인 역할을 하는것 같습니다.

일단 두 친구들의 역할과 특징에 대해서 알아보겠습니다.

역할 분리와 관심사의 분리

  • case class는 주로 데이터를 담는 “모델” 역할을 합니다.
    • 불변성을 유지하고, equals, hashCode, toString과 패턴 매칭에 유용한 unapply 메소드를 자동으로 생성 합니다.
  • companion object
    • 그 case class와 관련된 부가 기능(예: 팩토리 메소드, 유틸리티 함수, 상수 등)을 제공 합니다.
    • 이를 통해 인스턴스 생성 방식이나 초기화 로직을 캡슐화할 수 있습니다.

자동 코드 생성

case class를 선언하면, 컴파일러가 companion object 안에 기본적인 apply, unapply 메소드를 자동으로 생성 합니다.
덕분에 개발자는 데이터를 표현하는 클래스와, 인스턴스 생성을 위한 로직을 명확히 분리하여 관리할 수 있습니다.
즉, 코드가 명료하고 만들어주니 편합니다.

함수형 프로그래밍의 장점

Scala는 함수형 프로그래밍을 지원하므로, 불변 객체패턴 매칭을 자주 사용합니다.
case class는 이런 패턴에 최적화되어 있고, companion object는 이를 뒷받침하는 역할을 수행합니다.
이런 구조 덕분에 코드가 짧고 읽기 쉽게 작성할 수 있어서 유지보수가 편해집니다.

결론적으로  case class와 companion object의 분리는 편의성명확한 역할 분담을 위해 도입된 디자인 패턴이라 볼 수 있습니다.
개발자가 데이터를 쉽게 다루고, 동시에 관련 기능을 깔끔하게 관리할 수 있도록 돕기 위한 구조 입니다.

이런 특징들을 기반으로 Akka라는 친구도 있습니다.
하나씩 정리하면서 머릿속에 남겨보아요!

참고 : 2025.03.31 - [Data Platform/Scala] - companion class와 companion object이 차이점은?

그런데!!! case object라는 것도 있습니다ㅋㅋㅋㅋ
이녀석은 상태가 없는 싱글톤 객체를 표현하기 위한 불변/메시지 타입 입니다.
case object Done 처럼 object니까 당연히 싱글톤입니다.
case가 붙어있으므로 패턴매칭을 사용 합니다.

그러면 언제쓰나?
패턴매칭용 메시지에 완료 됐다는 신호나 초기호 명령 등 값이나 상태를 따로 들고 있을 필요가 없을 때  사용합니다.

sealed trait TaskMessage
case class Work(data: String) extends TaskMessage
case object Done extends TaskMessage
def handle(msg: TaskMessage): Unit = msg match {
  case Work(d) => println(s"Doing work: $d")
  case Done    => println("All done!")
}

object와 case object를 비교해보면 아래와 같습니다.

object case object
단순 싱글톤 싱글톤 + 패턴 매칭 지원
패턴 매칭 시 match문에서 사용 X macth문에서 case로 사용할 수 있음
unapply 없음 자동 생성

요약하면,

case object는 값이 필요 없는 메시지나 상태를 표현할 때 쓰는 싱글톤 + 패턴 매칭용 클래스!
패턴 매칭 가능한 싱글톤 -> case object

예) Done, Ping, Init, Stop같은 값 없는 메시지는 전부 case object로 선언해서 match할 수 있습니다.

sealed trait Command
case object Start extends Command
case object Stop extends Command

def handle(cmd: Command) = cmd match {
  case Start => println("시작!")
  case Stop  => println("중지!")
}



끝~

 

 

 

 

 

반응형