2013-05-27 3 views
1

데이터 (이 경우 remoteIdKey)가 오래된 경우에만 서버에 전화를 걸려고합니다. 여기에 내가하고 있어요 방법은 다음과 같습니다개체를 변경할 수 없게 만들 수 없습니다.

object remoteCaller { 

def getRemoteKeyId = { 

    // do we need to get the data from the server? 
    if (currentTime - lastCallTime >= 1000) { 
     remoteId = makeRemoteCall 
     lastCallTime = currentTime 
    } 

    remoteId 
    } 

    private var remoteId = 0 
    private def currentTime = //.... 
    private var lastCallTime = //.... 
    private def makeRemoteCall = { //remote call to the server to get the remote Id key} 
} 

문제는 내가 그러므로 var 대신 val를 사용 remoteCaller의 상태를 돌연변이 때문이다. 그리고 클래스 대신 객체를 사용하여 그 인스턴스 만 존재하게하십시오.

remoteCaller를 변경하지 못하게하려면 어떻게해야합니까? 또는 어떻게 변형 기능이없는 기능 스타일로 만들 수 있습니까?

+2

을 나는 당신이 당신이 해결하려고하는 문제는 본질적으로 상태인지 여부를 고려해야한다고 생각합니다. 나에게 구형이 될 수있는 것들은 변경 가능해야만하는 것처럼 보인다. 모든 I/O는 본질적으로 변경 가능하므로 순전히 기능적 접근 방식의 이점을 누리지 못할 수 있습니다. 가능한 한 자주 val을 사용하는 것이 가장 좋은 방법이지만, 반드시 필수는 아닙니다. – Felix

+0

상황을 그대로 유지하기로 결정하면 동기화 문제가 발생합니다. 이것을 두 개로 나누는 것이 좋습니다. 하나는 고정 된 간격으로 원격 데이터를 가져오고 다른 하나는 해당 데이터를 가져 오는 작업입니다. 원격 호출을하는 동안 잠그는 것은 이상적이지 않습니다. 이렇게하면 정기적 인 태스크가 변수를 업데이트 할 때 변수를 변경하는 동안 만 잠글 수 있습니다. – cmbaxter

+0

@cmbaxter, 어떻게해야합니까? 그래도 이것에 대해서. –

답변

1

문제는 당신이 상호 배타적 두 가지를 달성하고자하는 것 같다 :

  1. 변경 가능한 상태에서만 발스와
  2. object 그것을

@Felix 이미이 있기 때문에 진술 한, 변하기 쉬운 국가가 본질적으로 나쁘지 않다. 이 경우에는 불필요한 복잡성을 피하는 데 도움이된다면 특히 좋습니다. 그러나 그럼에도 불구하고, 당신은 그것을 조금씩 청소할 수 있습니다. 우선, 나는 당신이 현재 가지고있는 변경 가능한 상태를 새로운 클래스로 감쌀 것이다. 예를 들면 : 당신의 RemoteCaller 객체에서

case class RemoteCall(remoteId: Int, lastCallTime: Int) { 
    def refresh():RemoteCall = { 
     if (currentTime - lastCallTime >= 1000) { 
      RemoteCall(makeRemoteCall, currentTime) 
     } else { 
      this 
     } 
    } 

    private def makeRemoteCall = { ... } 
} 

, 당신은 다음과 같이 뭔가를 할 거라고 :

object RemoteCaller { 

    // Your entire mutable state wrapped in a case class 
    private var remoteCall:RemoteCall = ... 

    def getRemoteKeyId = { 
     remoteCall = remoteCall.refresh 
     remoteCall.remoteId 
    } 

} 
+0

하지만 여전히 RemoteCaller에는 변경할 수있는 필드 인 var remoteCall이 있습니다. –

+0

그래, 내가 말했듯이, 단지 모순이 될만한 가치가있는 변경 가능한 상태의 객체를 갖는 것은 불가능합니다. 가능한 경우 변경 가능한 상태를 피하는 것이 좋지만, 그럼에도 불구하고 간단하게하기 위해 'var'을 사용할 수도 있습니다. – fresskoma

+0

궁금한데 왜 RemoteCall을 사례 클래스로 만들었습니까? –

관련 문제