Fork me on GitHub

Friday, November 15, 2013

Redesign of LocalServiceConnection

For the current version of Scaloid, the type of LocalServiceConnection.service is [S <: LocalService]. This value is null if the service is not yet connected. So it is exposed to the possibility of NullPointerException. To avoid the exception, users must check that the service is connected, as shown below:

class MyService extends LocalService {
  def getNumber(): Int = 3
}

class Activity extends SActivity {
  val number = new LocalServiceConnection[MyService]

  def onButtonClick(v:View) {
    val num = if(number.connected) number.service.getNumber() else 0
    doSomethingWith(num)
  }
}

The problem is that the checking is very easy to forget. So I changed the type of LocalServiceConnection.service to Option[S], so that the possibility of NPE goes away. Moreover, I added some additional helper methods that decreases clutters from your code:

def onButtonClick(v:View) {
  val num = number(_.getNumber(), 0)
  doSomethingWith(num)
}

The method LocalServiceConnection.apply[T](f: S => T, defaultVal: T): T returns the result of the function f if the service is connected, and returns defaultVal otherwise. This is far more cleaner than the previous one.

If we don't want to return something, and therefore we don't have any default value, we can use it as:
def onButtonClick(v:View) {
  number(s => doSomethingWith(s.getNumber()))
}
We often tests some condition and evaluates different expression according to the condition:
def onButtonClick(v:View) {
  val result = if(number(_.getNumber(), 0) > 10) 
                 "10 < " + number(_.getNumber()) else "fail"
  doSomethingWith(result)
}
It can also be reduced to:
def onButtonClick(v:View) {
  val result = number(_.getNumber() > 10, "10 < " + _.getNumber(), "fail")
  doSomethingWith(result)
}

Because we have a breaking change, this feature will be shipped with Scaloid 3.0. You can evaluate this feature from the first milestone release. For a maven project:
<dependency>
    <groupId>org.scaloidscaloid_2.10</artifactId>
    <version>3.0-8-M1</version>
</dependency>
or for an sbt project:
libraryDependencies += "org.scaloid" %% "scaloid" % "3.0-8-M1"

No comments:

Post a Comment