Ответ 1
На самом деле существует множество способов, которыми вы можете это сделать. Я перечислил два из метода OO (похоже на то, что предлагает @Randal Schulz) и еще один функциональный способ. Для первого возможного решения вы можете сделать что-то простое:
case class MessageA(s:String)
case class MessageB(i:Int)
case class MessageC(d:Double)
trait MyActor extends Actor{
def receive = {
case a:MessageA =>
handleMessageA(a)
case b:MessageB =>
handleMessageB(b)
case c:MessageC =>
handleMessageC(c)
}
def handleMessageA(a:MessageA)
def handleMessageB(b:MessageB) = {
//do handling here
}
def handleMessageC(c:MessageC)
}
class MyActor1 extends MyActor{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class MyActor2 extends MyActor{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
При таком подходе вы определяете в основном абстрактного actor impl, где функция receive
определена для всех обработанных сообщений. Сообщения делегируются def
, где будет реальная бизнес-логика. Два абстрактных, позволяя конкретным классам определять обработку, и один полностью реализован для случая, когда логика не должна различаться.
Теперь вариант для этого подхода с использованием шаблона стратегии:
trait MessageHandlingStrategy{
def handleMessageA(a:MessageA)
def handleMessageB(b:MessageB) = {
//do handling here
}
def handleMessageC(c:MessageC)
}
class Strategy1 extends MessageHandlingStrategy{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class Strategy2 extends MessageHandlingStrategy{
def handleMessageA(a:MessageA) = {}
def handleMessageC(c:MessageC) = {}
}
class MyActor(strategy:MessageHandlingStrategy) extends Actor{
def receive = {
case a:MessageA =>
strategy.handleMessageA(a)
case b:MessageB =>
strategy.handleMessageB(b)
case c:MessageC =>
strategy.handleMessageC(c)
}
}
Здесь подход заключается в передаче в классе стратегии во время построения, который определяет обработку для a и c, причем b снова обрабатывается одинаково независимо. Эти два подхода довольно похожи и достигают одной и той же цели. Последний подход использует частичную цепочку функций и может выглядеть так:
trait MessageAHandling{
self: Actor =>
def handleA1:Receive = {
case a:MessageA => //handle way 1
}
def handleA2:Receive = {
case a:MessageA => //handle way 2
}
}
trait MessageBHandling{
self: Actor =>
def handleB:Receive = {
case b:MessageB => //handle b
}
}
trait MessageCHandling{
self: Actor =>
def handleC1:Receive = {
case c:MessageC => //handle way 1
}
def handleC2:Receive = {
case c:MessageC => //handle way 2
}
}
class MyActor1 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{
def receive = handleA1 orElse handleB orElse handleC1
}
class MyActor2 extends Actor with MessageAHandling with MessageBHandling with MessageCHandling{
def receive = handleA2 orElse handleB orElse handleC2
}
Здесь показаны некоторые признаки, которые определяют поведение обработки сообщений для 3 типов сообщений. Конкретные участники смешиваются в этих чертах, а затем выбирают, какое поведение они хотят, создавая свою функцию receive
, используя частичную цепочку функций.
Есть, вероятно, много других способов сделать то, что вы ищете, но я просто подумал, что я брошу несколько вариантов для вас. Надеюсь, поможет.