问题 演员信息应该扩展一个共同的特征吗?


在正确使用scala(和akka)actor框架的大多数示例中,人们倾向于从单个特征派生每条消息。例如:

trait Message
object Ping extends Message
object Pong extends Message

但是,在Scala和Akka中,消息接收都没有输入。有没有理由实施共同特征?


2350
2018-06-12 14:20


起源



答案:


这实际上取决于你想要达到的目标。例如,我最近构建了一个小型应用程序,它使用具有多种类型的actor的actor,以及一个或多或少像路由器一样的管理角色。例如,现在,工作人员可以收到许多不同的消息 FooBar 和 Baz。如果没有Supertype,在管理演员中,我必须写下这样的东西:

react {
    case x:Foo | x:Bar | x:Baz => worker ! x
}

这显然是不必要的冗长。所以在这种情况下,超类型 WorkerMessage 会有很多意义,因为它简化了你的代码:

react {
    case x:WorkerMessage => worker ! x
}

另一方面,这使得消息 FooBar 和 Baz 除了被WorkerActors使用之外,几乎无法用于任何其他目的。如果你有消息 Stop 要么 Init 例如,这可能会很糟糕,因为你需要在整个地方重新定义它。

所以,如果你知道你只有那些不传递信息的演员(也就是说,他们自己处理它们),那么我猜你没有超类型就可以了。

我想人们默认情况下或多或少会这样做的原因是,如果你以后改变你的代码,你不必在之后创建特征,因为你已经在开始时做了。

就个人而言,我总是尽量避免不必要的开销,所以除非我真的需要,否则我可能不会定义超类型。另外,我真的不知道创建超类型是否对性能有任何影响,但我很有趣。


5
2018-06-12 16:26





  1. 两者都有 scala.actors (通过 InputChannel[T] 要么 Reactor[T])和Akka(TypedActor你可以设置传入消息的类型边界;

  2. 在大多数示例中,消息扩展了一个 sealed trait。这样做有两个原因:

    • 如果你的actor的消息处理程序(部分函数)没有涵盖扩展特征的所有消息,编译器 生成警告;

    • sealed trait 只能在定义特征的源文件中扩展,因此,客户端无法定义扩展特征的消息;


5
2018-06-12 17:16



好的,我现在看到了scala.actors的原因。但是,对于akka类型的actor你没有定义消息,你只需要调用你的接口方法并等待魔法发生。密封的特性是有用的,但如果我没记错的话,Akka接收再次是部分功能[Any,Unit],所以不检查是否有丢失的情况。 - paradigmatic


答案:


这实际上取决于你想要达到的目标。例如,我最近构建了一个小型应用程序,它使用具有多种类型的actor的actor,以及一个或多或少像路由器一样的管理角色。例如,现在,工作人员可以收到许多不同的消息 FooBar 和 Baz。如果没有Supertype,在管理演员中,我必须写下这样的东西:

react {
    case x:Foo | x:Bar | x:Baz => worker ! x
}

这显然是不必要的冗长。所以在这种情况下,超类型 WorkerMessage 会有很多意义,因为它简化了你的代码:

react {
    case x:WorkerMessage => worker ! x
}

另一方面,这使得消息 FooBar 和 Baz 除了被WorkerActors使用之外,几乎无法用于任何其他目的。如果你有消息 Stop 要么 Init 例如,这可能会很糟糕,因为你需要在整个地方重新定义它。

所以,如果你知道你只有那些不传递信息的演员(也就是说,他们自己处理它们),那么我猜你没有超类型就可以了。

我想人们默认情况下或多或少会这样做的原因是,如果你以后改变你的代码,你不必在之后创建特征,因为你已经在开始时做了。

就个人而言,我总是尽量避免不必要的开销,所以除非我真的需要,否则我可能不会定义超类型。另外,我真的不知道创建超类型是否对性能有任何影响,但我很有趣。


5
2018-06-12 16:26





  1. 两者都有 scala.actors (通过 InputChannel[T] 要么 Reactor[T])和Akka(TypedActor你可以设置传入消息的类型边界;

  2. 在大多数示例中,消息扩展了一个 sealed trait。这样做有两个原因:

    • 如果你的actor的消息处理程序(部分函数)没有涵盖扩展特征的所有消息,编译器 生成警告;

    • sealed trait 只能在定义特征的源文件中扩展,因此,客户端无法定义扩展特征的消息;


5
2018-06-12 17:16



好的,我现在看到了scala.actors的原因。但是,对于akka类型的actor你没有定义消息,你只需要调用你的接口方法并等待魔法发生。密封的特性是有用的,但如果我没记错的话,Akka接收再次是部分功能[Any,Unit],所以不检查是否有丢失的情况。 - paradigmatic


这不是强制性的,但它是OO设计的东西。为应用程序域消息提供抽象类型是一种更好的设计。因此,在我们的应用程序代码中处理Messages时,您可以获得多态性。

   
trait Message

object Ping extends Message
objet Pong extends Message

object Stop
  

例如,如果应用程序中的某个位置必须处理大量消息而不管其特定类型(Ping或Pong),则将它们全部视为Message类型的对象。 这说得通?不是吗?


0
2018-06-12 15:16



如果有几个特征可以实现,那就有意义了。但是,如果所有消息都实现相同的单父特征,则您的参数无效。 - paradigmatic