Scala Actors - 转换基于 OOP 的方法时有什么建议吗?

Scala Actors - any suggestions when converting OOP based approach?

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

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

如果我们想模拟并发,例如许多客户一次购买商品我们投入某种线程(例如通过 ExecutorService)。基本上每个 Customer 然后实现 Runnable 接口及其 运行() 方法调用,例如shop.buy(这个,项目,数量)。由于我们要避免由于多个线程可能同时修改共享数据而导致数据损坏,因此我们必须使用同步。所以最典型的做法是同步 shop.buy() 方法。

现在让我们继续讨论基于 Actor 的方法。我的理解是,Shop 和每个 Customer 现在都变成了 Actors,他们不是直接在 shop 上调用 buy() 方法,而是向 shop 发送消息。但是困难来了。

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

回答您的问题:

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

1) 您的协议,例如商店、订单、卖家、买家等之间的交互,应该封装在 actor 中(每个协议一个 actor class,每个状态一个实例)。简单地说,actor 应该管理任何(可变的)状态,在请求之间改变,比如 current basket/order。例如,您可能为每个篮子都有一个 actor,它将包含有关所选项目的信息并接收诸如 AddItemRemoveItemExecuteOrder 之类的命令。 所以你不需要每个业务实体的参与者,你需要每个业务流程的参与者

此外,还有一些best practices and also recommendations about managing concurrency with routers

P.S。最近的基于 JavaEE 的方法是 EJB 及其实体(如 case-classes)和消息驱动的 bean(如参与者)。