Scala Actors - 转换基于OOP的方法时的任何建议?

时间:2015-05-16 18:47:03

标签: scala oop concurrency akka actor

我正在学习Scala及其Actors(通过Akka lib)处理并发的方法。在尝试将典型的OOP(思考 - Java风格的OOP)场景转换为基于Actor的场景时,我遇到了一些问题。

让我们考虑过度使用的电子商务示例Webstore,其中客户正在制作包含项目的订单。如果以OOP样式进行模拟,您最终会得到适当命名的域模型类,这些类通过相互调用方法在它们之间进行交互。

如果我们想要模拟并发性,例如许多客户一次购买物品我们会投入某种线程(例如通过ExecutorService)。基本上每个Customer然后实现Runnable接口及其run()方法调用,例如shop.buy(this,item,amount)。由于我们希望避免由可能同时修改共享数据的许多线程引起的数据损坏,因此我们必须使用同步。所以最常见的事情是同步shop.buy()方法。

现在让我们转到基于Actor的方法。据我所知,Shop和每个客户现在成为Actors,而不是直接在商店上调用buy()方法,向商店发送消息。但是这里遇到了困难。

  1. 是否所有其他域模型(Order,Item)都成为Actors,并且所有域模型之间的所有通信都是消息驱动的?换句话说,通过方法调用在域模型之间留下一些OOP样式交互是否可行是一个问题。例如,在基于OOP的方法中,Order通常会引用List,当用户通过在buy()方法中调用add(item)来购买时,可以填充List。这种(和类似的)交互是否必须通过消息传递进行重新构建,以充分利用基于Actor的方法?换句话说,我们何时直接与演员的内部状态沟通,何时将内部状态提取给另一个演员?这是一个问题?
  2. 在基于OOP的解决方案中,您将传递给类的方法实例。我在文档中读到,在Actor模型中,我应该传递不可变的消息。因此,如果我理解正确,您只需要发送一些数据,而不是消息对象本身,这样就可以识别出哪些实体需要处理,例如通过发送他们的ID以及您想要执行的操作类型。

1 个答案:

答案 0 :(得分:3)

回答你的问题:

2)您的域模型(包括商店,订单,买家,卖家,商品)应使用不可变的案例类进行描述。参与者应该交换(不可变)命令,这些命令可以使用这些类,例如AddItem(count: Int, i: Item) - AddItem case class表示命令并封装名为Item的业务实体。

1)您的协议,例如商店,订单,卖家,买家等之间的互动应该封装在actor内(每个协议一个actor类,每个州一个实例)。简单地说,演员应该管理任何(可变的)状态,在请求之间切换,例如当前购物篮/订单。例如,您可以为每个购物篮配备演员,其中包含有关所选项目的信息并接收AddItemRemoveItemExecuteOrder等命令。 因此,您不需要每个业务实体的演员,您需要每个业务流程的演员

此外,还有一些best practices以及有关使用routers管理并发的建议。

P.S。最近的基于JavaEE的方法是EJB及其实体(作为案例类)和消息驱动的bean(作为actor)。