398
2
기본기 다지기
8.9
내포된 타입
스칼라에서는 타입 선언과 정의를 내포시킬 있다. 예를 들어 특정 타입에만 있는 예외나 다른
유용한 타입을 객체 안에 정의하는 경우가 흔히 있다. 다음은 데이터베이스 계층을 전체적으로
보여준다.
//
src
/
main
/
scala
/
progscala2
/
basicoop
/
NestedTypes
.
scala
object Database
{
//
case class ResultSet
(/*...*/)
//
case class Connection
(/*...*/)
//
case class DatabaseException
(
message
:
String
,
cause
:
Throwable
)
extends
RuntimeException
(
message
,
cause
)
sealed trait Status
//
case object Disconnected extends Status
case class Connected
(
connection
:
Connection
)
extends Status
case class QuerySucceeded
(
results
:
ResultSet
)
extends Status
case class QueryFailed
(
e
:
DatabaseException
)
extends Status
}
class Database
{
import Database
.
_
def connect
(
server
:
String
):
Status
=
???
//
def disconnect
():
Status
=
???
def query
(/*...*/):
Status
=
???
}
데이터베이스를 위한 단순한 인터페이스
질의 결과 집합
result
set
담는다. 전체적인 모습을 보여주는 것과 관계없는 자세한 부분은
략했다.
연결
connection
pool
이나 다른 정보를 담는다.
상태에 대해 봉인한 계층구조를 사용한다. 따라서 모든 가능한 값이 여기에서 정의된다.
399
8
스칼라 객체지향 프로그래밍
스턴스가 실제로는 아무런 상태 정보를 저장하지 않는다면
case
object
를 사용하라. 이런 객
체들은 마치 상태를 가리키는 ‘플래그’처럼 작동한다.
???
Predef
정의된 메서드다. 하는 일은 그냥 예외를 던지는 것이다. 구현하지 않은 메서
드를 표시하기 위해
???
사용한다. 기능은 상대적으로 최근에 라이브러리에 반영되었다.
TIP
클래스에 추가 상태 정보를 저장하는 필드가 없다면, 케이스 객체를 사용할 것을 고려하라.
??? 메서드는 개발 중인 코드에서 구현해야 할 메서드를 표시해놓고 싶을 때 매우 편리하다. 코드는 컴파일할
있지만, ???지정한 메서드를 호출할 수는 없다 !
케이스 객체에서 내가 찾은 ‘구멍’이 군데 있다. 다음 세션을 보라.
scala
>
case object Foo
defined object Foo
scala
>
Foo
.
hashCode
res0
:
Int
=
70822
scala
>
"
Foo
".
hashCode
res1
:
Int
=
70822
case
object
를 위해 컴파일러가 만든
hashCode
는 분명히 그냥 객체의 이름을 해시에 사용한
다. 객체의 패키지나 객체 안의 필드는 무시한다. 이는
hashCode
구현이 강력해야 하는 경우
에는
case
object
사용하는 것이 위험할 있다는 의미다.
CAUTION
_
해시 기반의 집합이나 맵과 같이
hashCode
강력해야 하는 경우에는
case
object
사용
하는 것을 피하라.

Get 프로그래밍 스칼라: 실용적인 스칼라 활용법을 익히는 가장 확실한 실전 바이블 (2.11.x 버전 기반) now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.