【问题标题】:Scala Actors - any suggestions when converting OOP based approach?Scala Actors - 在转换基于 OOP 的方法时有什么建议吗?
【发布时间】:2015-07-28 13:22:05
【问题描述】:

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

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

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

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

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

【问题讨论】:

  • 保持简单(即避免所有这些)。问题解决了。

标签: scala oop concurrency akka actor


【解决方案1】:

回答您的问题:

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

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

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

附:最接近的基于 JavaEE 的方法是带有实体(作为案例类)和消息驱动 bean(作为参与者)的 EJB。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-02-26
    • 2010-12-31
    • 2012-11-24
    • 1970-01-01
    • 2011-02-21
    • 1970-01-01
    • 2011-06-06
    • 1970-01-01
    相关资源
    最近更新 更多