Warning: Trying to access array offset on value of type bool in /home/www/blog/wp-content/themes/catch-box/functions.php on line 1079

withService(myService) {…}

If we are using e.g. Service objects (and a method called “create” on it), it is a common case that we have to create the object and do some open and close operations on it like this:

{
   val s:Service = new Service()
   s.open
   s.create("test")
   s.close
}

In Scala we can use closures as a block operation refering to a instance of a service object (s is the instance of the Service object. The method “withService” gives the possibility to do the open and close method calls on the Service object. This result would look like this:

withService(s) { s =>
    val str = "test"
    s.create(str)
}

Next thing is to get rid of the “s =>” statement. This can be done by using a ThreadLocal variable. Together with a ThreadLocal singleton pattern we get finally:

class ScalaThreadLocal[T] extends ThreadLocal[Option[T]] {
  override protected def initialValue: Option[T] = None
}

object MyServiceObject {
  private val s = new ScalaThreadLocal[MyServiceObject]()

  def apply() = s get match {
    case Some(x) => x
    case None => s set Option(new MyServiceObject) ; s.get.get
  }
}

trait MyCRUDServiceInterface {
  def create(o:Any)
  def read:Any
  def update(o:Any)
  def delete(o:Any)
  def open
  def close
}

class MyServiceObject extends MyCRUDServiceInterface {
  def create(o:Any) = println("called create: " + o)
  def read:Any = println("called read")
  def update(o:Any) = println("called update: " + o)
  def delete(o:Any) =  println("called delete: " + o)

  def open = println("open called")
  def close = println("close called")
}

trait UsingCRUD {
  var thisService:MyCRUDServiceInterface = null

  def create(o:Any) = thisService.create(o)
  def read:Any = thisService.read
  def update(o:Any) = thisService.update(o)
  def delete(o:Any) = thisService.delete(o)

  def withService(s:MyCRUDServiceInterface)(f: => Unit) = {
    thisService = s
    s.open
    f
    s.close
  }
}

class BusinessClassUsingService extends UsingCRUD {

  val s = MyServiceObject()

  withService(s) {
    val str = "test"
    create(str)
    read
    update(str)
    delete(str)
  }

}

object Main extends Application {
  val t = new BusinessClassUsingService()
}

The output is:

open called
called create: test
called read
called update: test
called delete: test
close called