2013-11-04 4 views
3

Option var 또는 일부 변경 가능한 변수를 사용하는 대신 지연된 초기화에 Futures and Promises를 사용하는 것이 적절합니까?지연 초기화를위한 선물 및 약속 사용에 적합합니까?

class IntFactory{ 
    val intPromise = Promise[Int] 
    def create() : Future[Int] = intPromise.future 
    def init (data : String) : Unit = intPromise success data.length 
} 

배우 또는 다른 클래스는 다음과 같이 사용할 수 있습니다 : : 같은 일을 잘못 아무것도

class MyActor(factory : IntFactory) extends Actor{ 
    val future_int = factory.create() 

    def receive = { 
    case (msg : String) => factory.init(msg) // Now the promise is fulfilled 
    } 
} 

있습니까

당신은 약속을 캡슐화하는 공장 클래스를 만들 수 있습니다 이? 액터를 예로 사용하는 것이 이상적이지는 않을 것입니다. 액터 (FSM 또는 FSM)를위한 더 나은 대안이 있다고 생각하기 때문입니다. 나는 현재 이것을 비 액터 클래스와 함께 사용할 것을 고려 중입니다. 인스턴스 변수 중 일부는 특정 이벤트가 발생할 때까지 아무 것도 없습니다. var 옵션을 사용하고 None으로 설정하는 대신이 작업을 고려했습니다. 이것이 나쁘다면 다른 대안은 무엇입니까?

는 편집 :

나는이 더 유용 할 수 있습니다 상황을 생각했다.

class MyActor(factory1 : IntFactory, factory2 : IntFactory) extends Actor{ 
    val future_int1 = factory1.create() 
    val future_int2 = factory2.create() 

    for{ 
    x <- future_int1 
    y <- future_int2 
    } // Do some stuff when both are complete 

    def receive = { 
    case "first" => factory1.init("first") 
    case "second" => factory2.init("second") 
    } 
} 

그럼 내가 얻을 때마다 아무도없는 어떤 것들을 확인하지 않았을 : 내가 초기화하는 데 필요한 여러 가지가 있고, 경우에 나는이 모든 일 때 내가 수행하고 싶었 일부 비동기 작업을했다 다른 조각.

더 편집 :

내 원래의 질문에 지정하지 못한 몇 가지 추가 정보 : 개체가 비동기에서 올 것이다 초기화 할 필요

  1. 데이터입니다.

  2. init 함수에 전달 된 데이터는 초기화에 필요합니다. 지금 예제가되도록 예제 코드를 편집했습니다.

  3. 나는 Akka를 사용하지 않습니다. 나는 Akka가 빠른 예를 함께 던지는 데 도움이 될 것이며 경험있는 Akka 사람들이 유용한 피드백을 제공 할 수 있다고 생각했습니다.

+0

이것은 빌더 패턴에서 잘 읽습니다. 한 번에 하나씩 뭔가 초기화 될 때 사용되었지만 사용하지 않았지만 런타임 전에 완료 될 수 있다는 점이 도움이됩니다. 그러면 컴파일러 오류가 발생합니다. 너무 일찍 액세스하려고 시도하십시오. http://nullary.blogspot.com/2011/10/builder-pattern-revisited-in-scala.html – LaloInDublin

+0

'lazy val'만으로 충분하지 않습니까? –

+0

@ Patrykíwiek 게으른 발을 사용하여 예제를 재 작업 할 수 있습니까? 어떻게해야할지 모르겠다. 내 초기화가 외부 비동기 이벤트의 데이터에 의존하기 때문에 작동 여부를 확신 할 수 없습니다. – mushroom

답변

2

예, 이것은 가변 변수 (Option)의 사용보다 더 나은 접근 방법입니다. 외부 이벤트를 기다리지 않고 언제든지 상태를 초기화 할 수 있고 비동기 적으로 수행 할 필요가없는 경우 @ Patryküwiek이 제안한 lazy val을 사용하면 상태를 초기화 할 수있는 경우가 훨씬 좋습니다. 당신의 IntFactory으로 판단

0

, 당신은 정말 (이 어디서나 사용할 아니에요)에 data 문자열을 필요로하지 않는, 그래서 기본 케이스는 다음과 같이 다시 작성할 수 생각 :의 말을하자,

class Foo { 
    lazy val first = { 
    Thread.sleep(2000) // Some computation, initialization etc. 
    25 
    } 
    lazy val second = { 
    Thread.sleep(1000) // Some computation, initialization etc. 
    11 
    } 
    def receive(s : String) = s match { 
    case "first" => first 
    case "second" => second 
    case _ => -1 
    } 
} 

을 지금 이 작업을 수행 :

val foo = new Foo() 
println(foo.receive("first")) // waiting for 2 seconds, initializing 
println(foo.receive("first")) // returns immediately 
println(foo.receive("second")) // waiting for 1 second, initializing 

이제 모두 firstsecond이 최대 한 번초기화 할 수 있습니다.

lazy val에 매개 변수를 전달할 수 없으므로 data 문자열이 초기화에 중요하게 중요하면 memoization (IMO)과 함께 팩토리 방법을 사용하는 것이 더 나을 것입니다.

+0

실제로 이것을 사용하면 init에 대한 입력이 필요합니다. 나의 예는 이것에 대해 아주 명확하지 않았다. 나는 가능한 한 많은 예제를 단순화하려고 노력 했었고 너무 멀리 갔다. 나는 메모로 공장 방법을 조사 할 것이다. – mushroom