Scala/Akka 组合模式(class 中的对象)

Scala/Akka composition pattern (object in class)

我是 Scala 的新手,但从我目前所见的代码中遇到了一种编码模式。这是我正在谈论的一个例子:

object TicketSeller {
  def props(event: String) = Props(new TicketSeller(event))

  case class Add(tickets: Vector[Ticket])

  case class Buy(tickets: Int)

  case class Ticket(id: Int)

  case class Tickets(event: String,
                     entries: Vector[Ticket] = Vector.empty[Ticket])

  case object GetEvent

  case object Cancel

}

class TicketSeller(event: String) extends Actor {

  import TicketSeller._

  var tickets = Vector.empty[Ticket]

  def receive = {
    case Add(newTickets) => tickets = tickets ++ newTickets
    case Buy(nrOfTickets) =>
      val entries = tickets.take(nrOfTickets).toVector
      if (entries.size >= nrOfTickets) {
        sender() ! Tickets(event, entries)
        tickets = tickets.drop(nrOfTickets)
      } else sender() ! Tickets(event)
    case GetEvent => sender() ! Some(BoxOffice.Event(event, tickets.size))
    case Cancel =>
      sender() ! Some(BoxOffice.Event(event, tickets.size))
      self ! PoisonPill
  }
}

注意 TicketSeller class 如何从 TicketSeller object

导入所有东西
  import TicketSeller._

我之前见过这种 "object in class" 模式,其中对象中的大部分(如果不是全部)都是大小写 classes。 为什么要这样做?有什么好处,它真的是一种模式,还是我对事物的了解不够深入,无法完全理解?

非常感谢!

如果您来自 Java 背景,static 成员将是最接近的类比。

在 classes 的情况下,class 中的嵌套 class 可能具有对所有者对象的隐式引用;此外,它还可以访问封闭对象的字段。如果 object 中有 class,则没有这种风险,因此出错的可能性要小得多。

同样,您在 class 中定义的所有内容都只能作为 class 的 实例 的一部分进行测试。因此,您的测试将需要实例化 class,为 event 提供一些值(这对大多数测试来说没有多大意义,增加了混乱),而 object members 你只是指那里的任何成员——他们可以访问的状态非常有限,他们需要实例化的状态已经存在.

PS。顺便说一下,Props(new TicketSeller(event)) 是另一个很好的例子。这里的做法是 完全没问题, 但是如果你把它移到 class 本身,它会变成 dangerous variant 原因完全相同:可见性封闭 class 的状态使得关闭封闭范围太容易了。

// NOT RECOMMENDED within another actor:
// encourages to close over enclosing class
val props7 = Props(new MyActor)

This method is not recommended to be used within another actor because it encourages to close over the enclosing scope, resulting in non-serializable Props and possibly race conditions (breaking the actor encapsulation). We will provide a macro-based solution in a future release which allows similar syntax without the headaches, at which point this variant will be properly deprecated. On the other hand using this variant in a Props factory in the actor’s companion object as documented under “Recommended Practices” below is completely fine.