代码之家  ›  专栏  ›  技术社区  ›  BefittingTheorem

作曲演员

  •  8
  • BefittingTheorem  · 技术社区  · 15 年前

    我实现了一个listenable/listener特性,可以添加到actors中。我想知道是否可以将这种风格的特质附加到演员身上,而不必显式地调用 侦听器处理程序 方法?

    我也希望在akka库中找到这个功能。是我遗漏了什么,还是有什么原因阿卡不包括这些?

    trait Listenable { this: Actor =>
        private var listeners: List[Actor] = Nil
    
        protected def listenerHandler: PartialFunction[Any, Unit] = {
            case AddListener(who) => listeners = who :: listeners
        }
    
        protected def notifyListeners(event: Any) = {
            listeners.foreach(_.send(event))
        }
    }
    
    class SomeActor extends Actor with Listenable
    {
        def receive = listenerHandler orElse {
            case Start => notifyListeners(Started())
            case Stop => notifyListeners(Stopped())
        }
    }
    
    5 回复  |  直到 12 年前
        1
  •  5
  •   Rex Kerr    15 年前

    为什么不延长 Actor 直接地,或者如果您希望非actors也可以被listenable,那么创建一个listenable actor,它使用listenable扩展actor?

    然后你会重写 receive 就像你在上面所做的那样(除了你想打电话给 super.receive 还有,是不是?--您只需要修改传入的函数)。

        2
  •  2
  •   Daniel C. Sobral    15 年前

    我建议你扩大演员范围,用 abstract override .

        3
  •  2
  •   Viktor Klang    12 年前

    为什么我以前没见过这个问题,呃,好吧,迟了总比没见过好:

    http://doc.akka.io/docs/akka/snapshot/scala/routing.html

        4
  •  0
  •   BefittingTheorem    15 年前

    下面是一个解决方案(示例从scala开始的修改版本):

    import se.scalablesolutions.akka.actor.Actor
    
    case class AddListener(who: Actor)
    case class RemoveListener(who: Actor)
    
    class ListenableActor extends Actor {
        private var listeners: List[Actor] = Nil
    
        def receive = {
            case AddListener(who) => listeners ::= who
            case RemoveListener(who) => listeners.filter(_ ne who)
        }
    
        protected def notifyListeners(event: Any) = {
            listeners.foreach(_.send(event))
        }
    }
    
    class ImplementingActor extends ListenableActor {
        override def receive = {
            super.receive orElse {
                case Message(content) => println(content)
            }
        }
    }