![](/api/v2/epubs/9788968482755/files/bg2c7.png)
710
4
부
고급 주제 및 실전 응용
자바와 달리, 스칼라에서는 애노테이션을 정의하기 위한 특별한 문법이 필요하지 않다. 다음은
implicitNotFound
(
http
://
bit
.
ly
/
1toohzB
)의 정의다.
package scala
.
annotation
final class implicitNotFound
(
msg
:
String
)
extends StaticAnnotation
{}
23.3
모듈로서의 트레이트
자바는 모듈의 단위로 클래스와 패키지를 제공하며,
JAR
파일을 가장 커다란 구성 요소 추상화
단위로 사용한다. 패키지는 가시성을 제어하는 데 한계가 있다는 것이 언제나 문제였다. 패키
지만으로는 공개적인 가시성으로부터 구현을 감추기에 충분히 실용적이지 않았다. 그래서 그
런 일을 해내는 사람이 별로 없었다. 스칼라는 가시성 규칙을 더 풍부하게 제공해서 이를 가능
하게 만들었다. 하지만 그런 가시성 규칙이 널리 활용되지는 않고 있다. 패키지 객체는 클라이
언트가 무엇을 사용해야 하고, 무엇을 사용하지 말아야 하는지 지정하는 또 다른 방법이다.
모듈화의 다른 중요한 목표는 조합을 가능케 하는 것이다. 스칼라의 트레이트는 조합 구성을 훌
륭하게 지원한다. 실제로 스칼라에서는 모듈을 정의하는 기법으로 클래스보다는 트레이트를 활
용한다.
14
.
6
절 ‘자기 타입 표기’에서 케이크 패턴을 사용하는 예를 봤다. 다음은 그 예제에서 중요한 부
분을 간추린 것이다.
//
src
/
main
/
scala
/
progscala2
/
typesystem
/
selftype
/
selftype
-
cake
-
pattern
.
sc
trait Persistence
{
def startPersistence
():
Unit
}
//
➊
trait Midtier
{
def startMidtier
():
Unit
}
trait UI
{
def startUI
():
Unit
}
trait Database extends Persistence
{
//
➋
def startPersistence
():
Unit
=
println
("
Starting Database
")
}
trait BizLogic extends Midtier
{
def startMidtier
():
Unit
=
println
("
Starting BizLogic
")
![](/api/v2/epubs/9788968482755/files/bg2c8.png)
711
23
장
애플리케이션 설계
}
trait WebUI extends UI
{
def startUI
():
Unit
=
println
("
Starting WebUI
")
}
trait App
{
self
:
Persistence with Midtier with UI
=
>
//
➌
def run
()
=
{
startPersistence
()
startMidtier
()
startUI
()
}
}
object MyApp extends App with Database with BizLogic with WebUI
//
➍
➊ 애플리케이션의 영속성, 중간 계층,
UI
계층의 트레이트를 정의한다.
➋ ‘구체적’인 동작을 트레이트로 구현한다.
➌ 각 계층을 어떻게 이어 붙일지 ‘뼈대’를 정의하는 트레이트 (추상 클래스도 가능함)를 정의한
다. 여기 있는 단순한 예제에서는
run
메서드가 각 계층을 시작하기만 한다.
➍
App
을 확장하고 각 계층의 동작을 구현하는 구체적 트레이트
3
개를 혼합하는
MyApp
객체를
정의한다.
각 트레이트 (
Persistence
,
Midtier
,
UI
)는 모듈의 추상화로 기능한다. 구체적인 구현은 각 트
레이트와 깔끔하게 분리된다. 이들을 조합해서 전체 애플리케이션을 만든다. 자기 타입 표기는
각각을 이어준다.
케이크 패턴은 의존관계 주입에 대한 대안으로 사용되었다 (
http
://
bit
.
ly
/
1tHZ8Qd
). 스칼라
컴파일러 자체를 구현하는 데도 케이크 패턴을 사용했다.
2
하지만 단점도 있다. ‘케이크’ 사이의 의존관계 그래프가 단순하지 않은 경우, 의존관계 간의 초
기화 순서에 문제가 생기는 경우가 자주 있다. 이럴 때는 지연값이나 필드 대신 메서드를 활용
하는 등의 우회적 해결 방법이 있다. 두 방법 모두 어떤 의존관계가 초기화될 때까지 그에 의존
하는 다른 값의 초기화를 늦춘다.
2
역주_ 마틴오더스키(
Martin
Odersky
)와마티아스젱거(
Matthias
Zenger
)의“확장가능한구성요소추상화(
Scalable
Component
Abstraction
),
OOPSLA
,
2005
”
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.