2013-02-01 3 views
3

스칼라 프로젝트에 구성 구성 요소가 있습니다.케이크 패턴 : 인스턴스를 공유하는 방법은 무엇입니까?

분명히이 구성 요소의 인스턴스를 두 개 이상 갖고 싶지 않습니다. 나는 케이크 패턴을 사용하고 있습니다,하지만 난 내 요구 사항에 맞도록 조정할하는 방법을 잘 모르겠어요 :

// Library 
// ================================================= 
trait ConfigComp { 

    trait Config { 
    def get(k: String): String 
    } 

    def config: Config 
} 

trait QueueComp { 
    self: ConfigComp => 

    class Queue { 
    val key = config.get("some-key") 
    } 

    lazy val queue = new Queue 
} 

// Application 
// ================================================= 

trait MyConfig extends ConfigComp { 

    lazy val config = new Config { 
    println("INITIALIZING CONFIG") 

    def get(k: String) = "value" 
    } 
} 

object Frontend extends QueueComp with MyConfig 
object Backend extends QueueComp with MyConfig 

Frontend.queue.key 
Backend.queue.key 

인쇄하기 :

INITIALIZING CONFIG 
INITIALIZING CONFIG 

케이크 패턴 주로 만들려면Config의 익명 인스턴스?

+2

당신이 뭔가 클래스 사이에 (하나 개의 모범에 존재하는, 즉 뭔가를) 공유하고자 할 경우 유형 넣어 : 이제 다음에 코드를 변경할 수있는, 좀 더 명확하게하려면 이 특성의 개체 및 액세스 개체 값이 혼합됩니다. –

+0

고마워요, 나는 그것을 시도하고 "호환되지 않는 형식"오류가 있습니다 : https://gist.github.com/4693853 – stephanos

+1

아래 주석 참조 너의 발췌 문장. 누군가가 "호환되지 않는 유형"오류를 설명 할 수있을 때까지 기다리지 만 일시적인 해결 방법으로는 잘 작동합니다. –

답변

3

이와 비슷한?

// Library 
// ================================================= 
trait Config { 
    def get(k: String): String 
} 

trait ConfigComp { 
    def config: Config 
} 

trait QueueComp { 
    self: ConfigComp => 
    class Queue { 
    val key = config.get("some-key") 
    } 
    lazy val queue = new Queue 
} 

// Application 
// ================================================= 

object SingleConfig extends ConfigComp { 
    lazy val config = new Config { 
    println("INITIALIZING CONFIG") 
    def get(k: String) = "value" 
    } 
} 

object Frontend extends QueueComp with ConfigComp { 
    val config = SingleConfig.config 
} 
object Backend extends QueueComp with ConfigComp { 
    val config = SingleConfig.config 
} 

Frontend.queue.key 
Backend.queue.key 

당신의 Config 특성이 ConfigComp 내부에 위치하는 경우, 나는이 유형의 오류를 해결하지 못했습니다 : 언급 OM-NOM-NOM로

error: type mismatch; 
found : MyConfig.Config 
required: Frontend.Config 
    (which expands to) Frontend.Config 
       override def config = MyConfig.config 

error: type mismatch; 
found : MyConfig.Config 
required: Backend.Config 
    (which expands to) Backend.Config 
       override def config = MyConfig.config 
+0

특성에서'Config'를 빼내는 것이 유일한 해결책 인 것 같습니다. 그래서이 설명을 받아 들여 – stephanos

1

을, 당신은 싱글 톤을 사용하고자하는, 그래서있어 MyConfig은 객체에서 초기화되는 config을 사용해야합니다. 당신의 gist, 다음과 같은 오류에서 두 번째 질문에 :

[error] overriding method config in trait ConfigComp of type => MyConfig.this.Config; 
[error] lazy value config has incompatible type 
[error] lazy val config = MyConfig.config 
[error]   ^
[error] one error found 

은 기본적으로 정확하게 문제를 알려줍니다. MyConfig.this.Config은 개체 MyConfig.this.Config과 같지 않습니다.

여기
object MyConfigSingleton extends ConfigComp { 
    val config = new Config { 
    println("INITIALIZING CONFIG") 
    def get(k: String) = "value" 
    } 
} 

trait MyConfig extends ConfigComp { 
    lazy val config = MyConfigSingleton.config 
} 

, MyConfig.this.Config != MyConfigSingleton.this.Config

+0

감사합니다! -'Config'가'ConfigComp' 내부에 중첩 된 해결책이없는 것처럼 보입니다. 어쨌든 나쁜 디자인 일 것입니다. ;-) – stephanos

관련 문제