Scala / Akka组合模式(课堂上的对象)

时间:2016-06-04 07:47:32

标签: scala akka composition

我对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 如何从TicketSeller 对象中导入所有内容

  import TicketSeller._

我之前看过这个“类中的对象”模式,其中对象中的大多数(如果不是全部)都是case类。 为什么这样做?有什么好处,它真的是一种模式,还是我还没有深入到完全理解的东西?

感谢一帮!

1 个答案:

答案 0 :(得分:1)

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

对于类,类中的嵌套类可能具有对所有者对象的隐式引用;另外,它可以访问封闭对象的字段。对于object范围内的课程,您没有这种风险,因此错误发生的可能性要小得多。

同样,您在class中定义的所有内容只能作为该类实例的一部分进行测试。因此,您的测试需要实例化该类,为event提供一些值(这对于大多数测试没有多大意义,增加了杂乱),而对于object成员,您只需要指的是那里的成员 - 他们有权访问的状态非常有限,他们需要实例化的状态是已经存在

PS。顺便提一下,Props(new TicketSeller(event))是另一个很好的榜样。它在这里完成的方式是完全正常,但是如果你把它移到类本身,它就会变成dangerous variant,原因完全相同:封闭类的可见性' s状态太容易关闭封闭的范围。

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

不建议在另一个actor中使用此方法,因为它鼓励关闭封闭范围,导致不可序列化的Props和可能的竞争条件(打破actor封装)。我们将在未来版本中提供基于宏的解决方案,该解决方案允许类似的语法而不会令人头疼,此时将适当地弃用此变体。另一方面,如下面“推荐实践”中所述,在演员的伴侣对象的道具工厂中使用此变体是完全正常的。