如何在akka中扩展超级演员的行为

时间:2017-09-29 07:29:29

标签: scala akka actor akka-http

我想使用akka actor实现CRUD操作。我是akka的新手,所以不知道akka演员的设计基础。

我想在多个子演员中分享akka演员的行为。

Fir示例我想保存并删除学生,教师和其他实体。

我为StudentDao.scala创建了演员

class StudentDao extends Actor with ActorLogging{

 override def Receive = {

    case Add(student) =>
      // Add to database
    case Delete =>
      //Delete from database     
   // Some other cases related to Student entity
  }
}
case object StudentDao{
  case class Add(user : Student)
  case class Delete(id : String)
}

同样我有TeacherDao.scala的演员

class TeacherDao extends Actor with ActorLogging{

 override def Receive = {

    case Add(teacher) =>
      // Add to database
    case Delete =>
      //Delete from database      
    // Some other cases related to teacher entity

  }
 }

object TeacherDao{
  case class Add(user : teacher)
  case class Delete(id : String)
}

我想为两个dao抽象删除方法。 所以我创建了BaseDao.scala

class BaseDao extends Actor with ActorLogging{

  override def Receive = {

    case Delete =>
      //Delete from database   dao.delete
  }

我如何使用基础演员进行抽象。

2 个答案:

答案 0 :(得分:1)

orElse是扩展演员行为的方法,因为演员的Receive只是PartialFunction[Any, Unit]的别名。以下是您的用例的具体说明。

首先,在必须与actor混合的特征中定义基本行为。为避免重复,请将Delete案例类移动到此特征的伴随对象中。

trait BaseDao { this: Actor with ActorLogging =>
  import BaseDao._

  def baseBehavior: Receive = {
    case Delete(id) =>
      log.info(s"Deleting $id from db")
      // delete from db
  }
}

object BaseDao {
  case class Delete(id: String)
}

然后,将上述特征混合到您的其他演员中,并使用orElse链接行为。请注意,我创建了虚拟StudentTeacher个案例类,以便编译此代码。 StudentDao

class StudentDao extends Actor with ActorLogging with BaseDao {
  import StudentDao._

  def studentBehavior: Receive = {
    case Add(student) =>
      log.info(s"Adding student: $student")
    // some other cases related to Student
  }

  def receive = studentBehavior orElse baseBehavior
}

object StudentDao {
  case class Add(user: Student)
}
case class Student(name: String)

TeacherDao

class TeacherDao extends Actor with ActorLogging with BaseDao {
  import TeacherDao._

  def teacherBehavior: Receive = {
    case Add(teacher) =>
      log.info(s"Adding teacher: $teacher")
    // some other cases related to Teacher
  }

  def receive = teacherBehavior orElse baseBehavior
}

object TeacherDao {
  case class Add(user: Teacher)
}
case class Teacher(name: String)

答案 1 :(得分:0)

您可以为基本actor创建一个特征,使用一个公共接收函数orElse另一个必须在子actor中实现的特性:

trait BaseActor extends Actor {

  override def receive: Receive = commonReceive orElse handleReceive

  def commonReceive: Receive = {
    case CommonMessage => // do something
  }

  def handleReceive: Receive
}

然后你的子演员只需要实现handleReceive:

class SubActor extends BaseActor {

  override def handleReceive: Receive = {
    case SpecificMessage => // do something
  }
}