2010-03-09 32 views
8

Tôi đã triển khai đặc điểm Nghe/Nghe có thể được thêm vào Diễn viên. Tôi tự hỏi nếu nó có thể đính kèm phong cách này của đặc điểm cho một diễn viên mà không cần phải rõ ràng gọi phương thức listenerHandler listenerHandler?Soạn diễn viên

Ngoài ra, tôi đã hy vọng tìm thấy chức năng này trong thư viện Akka. Tôi đang thiếu một cái gì đó hoặc là có một số lý do mà Akka sẽ không bao gồm điều này?

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()) 
    } 
} 

Trả lời

5

Tại sao không mở rộng Actor trực tiếp, hoặc nếu bạn muốn phi diễn viên được Listenable cũng có, tạo một ListenableActor kéo dài diễn viên với Listenable?

Sau đó, bạn sẽ ghi đè receive trong diễn viên như bạn đã thực hiện ở trên (ngoại trừ bạn cũng muốn gọi số super.receive, phải không? - bạn chỉ muốn sửa đổi chức năng được chuyển vào).

+0

Vâng này được điều này, trong cả hai trường hợp tôi sẽ phải nhớ để gọi TNDN super.receive hoặc * listenerHanlder * của cô ấy. Tôi đã tự hỏi nếu có một cơ chế trong Scala nói chung hoặc bất kỳ thư viện nào của diễn viên cho phép diễn viên thực hiện Listenable không phải làm bất cứ điều gì ngoại trừ nói: * với Listenable * –

+0

Nhưng bạn chỉ phải nói 'extendends ListenableActor' thay vì 'extends Actor'; bên trong 'ListenableActor' bạn đã ghi đè' receive' (và, có lẽ, 'receiveWithin'). Xem thêm câu trả lời của Daniel. –

2

Tôi đề nghị bạn mở rộng Actor và sử dụng abstract override.

0

Dưới đây là một giải pháp (một phiên bản sửa đổi của các ví dụ từ Beginning 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) 
     } 
    } 
} 
+0

Bạn vừa thay đổi 'trait' thành' class' ... –

Các vấn đề liên quan