실행 중인 메소드에서 호출 객체 인스턴스 참조를 자기 참조(self reference)라 한다. 

자바의 this와 동일하며, 스칼라에서도 this를 그대로 쓸 수 있다. 


case class Member(val name: String) {
def compare(that: Member): Boolean = {
if (this.name == that.name) true
else false
}
}


테스트 코드는 다음과 같다.

println(Member("samuel").compare(Member("samuel")))
println(Member("samuel").compare(Member("excel")))


결과는 다음과 같다.


true

false









this에 대한 추가 타입으로 self type annotation이고, this에 대한 앨리어스로 쓰는 self를 보자.

느낌은 바로 아래와 같다. 

trait Trait {
private[this] val self = this
}


이번에는 self 지시자를 테스트한다. 


trait Self {
self =>
val name = "outer"
val innerObject = new AnyRef {
val name = "inner"
println(name)
println(this.name)
println(self.name)
}
}

object Main extends App {
new AnyRef with Self
}

결과는 다음과 같다.


inner

inner

outer


트레이트에 self => 를 추가하면 멤버 필드는 트레이트가 소유한 것을 의미한다. 내부 클래스를 선언할 때, 내부 클래스의 동일한 변수를 참조할 때 self를 사용했다. 




물론, abstract class를 써도 동일한 결과는 발생한다. 



abstract class Self {
self =>
val name = "outer"
val innerObject = new AnyRef {
val name = "inner"
println(name)
println(this.name)
println(self.name)
}
}
class ChildSelf extends Self {
}

object Main extends App {
new ChildSelf
}


self를 name conflicting(이름 충돌)을 피하기 위해서 사용했다. 이 방법 외에, Injection하는 방식을 설명한다.



예는 마치 서비스 코드와 비슷하게 진행했다. 모르는 것이 훨씬 많아서 대충 코드를 썼다.


Controller - UserService (UserServiceImpl) 구조이다. 스칼라 Main 메소드에  withController with UserServiceImpl을 추가해서 믹스인(mixin)을 진행했다. 



trait UserService {
def printUser : Unit
}

trait UserServiceImpl extends UserService {
def printUser : Unit = println("samuel")
}

trait Controller {
self: UserService =>
}

object Main extends App with Controller with UserServiceImpl {
printUser
}


결과는 samuel으로 출력된다.



Controller 트레이트에서는 self:UserService 만 가르켰고 UserServiceImpl에 대한 정체는 알지 못한다.


Controller를 믹스인한 Main 객체에서 UserSerivceImpl 트레이트를 믹스인하면서, UserService를 통해 UserServiceImpl을 구했다. 


즉, Dependency Injection을 구현했다. 


스칼라에서는 이를 Cake Pattern 이라고 한다. 



재미있을 만한 링크는 다음에 있다. 


http://www.andrewrollins.com/2014/08/07/scala-cake-pattern-self-type-annotations-vs-inheritance/



https://coderwall.com/p/t_rapw/cake-pattern-in-scala-self-type-annotations-explicitly-typed-self-references-explained


http://marcus-christie.blogspot.kr/2014/03/scala-understanding-self-type.html



http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth




Posted by '김용환'
,