问题
I want to implement CRUD operation using akka actor. I am a new in akka so dont know the designing fundamentals of akka actors.
I want to share the behaviours of akka actors in multiple sub actors.
Fir example i want to save and delete student , teacher and other entity.
I have created actor for 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)
}
Same I have actor for 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)
}
I want to abstract delete method for both dao. So i have create BaseDao.scala
class BaseDao extends Actor with ActorLogging{
override def Receive = {
case Delete =>
//Delete from database dao.delete
}
how can i abstract using base actor.
回答1:
orElse is the way to extend actor behaviors, because an actor's Receive
is simply an alias for PartialFunction[Any, Unit]
. Below is a concrete illustration with your use case.
First, define the base behavior in a trait that must be mixed in with an actor. To avoid duplication, move the Delete
case class into this trait's companion object.
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)
}
Then, mix in the above trait into your other actors and chain the behaviors with orElse
. Note that I created dummy Student
and Teacher
case classes so that this code would compile. 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)
And 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)
回答2:
You can create a trait for the base actor, with a common receive function orElse
another one that has to be implemented in sub actors:
trait BaseActor extends Actor {
override def receive: Receive = commonReceive orElse handleReceive
def commonReceive: Receive = {
case CommonMessage => // do something
}
def handleReceive: Receive
}
And then your sub actors only have to implement handleReceive:
class SubActor extends BaseActor {
override def handleReceive: Receive = {
case SpecificMessage => // do something
}
}
来源:https://stackoverflow.com/questions/46483869/how-extend-behaviour-of-super-actor-in-akka