scala/sbEpOcBase.scala

// package scalabook.ep.oc

/**
 * Base definitions for the Operation-Centric approach.
 * @author Christos KK Loverdos
 */

// Base data
trait BaseD {
    def perform(op: BaseOp)
}

// Concrete data implementation.
// The initial set of concrete data decides which
// computeXXX methods are initially declared in BaseOp
class NumD(val value: Int) extends BaseD {
    def perform(op: BaseOp) {
      op.computeNumD(this)
    }
}

// Base operation.
// Includes methods for each concrete data defined previously
trait BaseOp {
    def computeNumD(data: BaseD)
}

// 1st concrete operation: evaluate the data
class EvalOp extends BaseOp {
  var result: Option[Int] = _

  def apply(data: BaseD) = {
    data.perform(this)
    result.get
  }

  def computeNumD(data: NumD) {
    this.result = Some(data.value)
  }
}

// 2nd concrete operation: string representation of data
class ReprOp extends BaseOp {
  var result: Option[String] = _

  def apply(data: BaseD) = {
    data.perform(this)
    result.get
  }

  def computeNumD(data: NumD) {
    this.result = Some(data.value.toString)
  }
}

// utility object for on-the-fly evaluations
object eval {
  def apply(data: BaseD) = new EvalOp()(data)
}

// utility object for on-the-fly string representations
object repr {
  def apply(data: BaseD) = new ReprOp()(data)
}