我最近重构了我的演员,并最终使用了许多辅助方法,这些方法是演员的一部分。这是正确的做法吗?所有的辅助方法都应该是它们自己的参与者吗?我如何进行分离?
public class MyActor extends UntypedActor {
public MyActor () {
}
@Override
public void onReceive(Object msg) throws Exception {
if ( msg instanceof doSomethingComplex) {
doSomethingComplex message = (doSomethingComplex) msg;
doSimple(message.prop);
}
private void doSimple(String prop){
doSimpler(prop);
....
}
private void doSimpler(String prop){
...
....
}
}
辅助方法应该在哪里?这些也应该是演员吗?
所有的辅助方法都应该是它们自己的参与者吗?我该如何进行分离?
在解决这些问题时,思考演员是什么会很有帮助。Derek Wyatt 在他的书Akka Concurrency 中,在演员和人之间进行了类比(以下摘自他书中免费提供的第四章):
您的日常世界充满了并发性。你把它强加给你自己和你周围的人,他们也把它强加给你。临界区和锁的现实世界等价物以及同步方法和数据都由您和您世界中的人自然地处理。人们通过一次只做一件事来管理这一点。我们喜欢假装我们可以同时处理多项任务,但事实并非如此。我们所做的任何有意义的事情都要求我们只做一件事。我们可以暂停该任务并稍后恢复,将其切换为其他工作,然后返回到它,但实际上一次做不止一件事并不在我们的驾驶室里。
那么如果我们想一次做不止一件事呢?答案很明显:我们只是使用不止一个人。世界上没有多少不是由一群有才华的人创造的,我们从中受益。
这就是为什么 actor 使我们的应用程序开发更加直观,我们的应用程序设计更易于推理:它们以我们的日常生活为模型。
在同一章的后面,他写道:
演员一次只做一件事;这就是并发模型。如果您希望同时发生不止一件事,那么您需要创建多个演员来完成这项工作。这很有道理,对吧?我们一直在说演员编程会大量借鉴您的日常生活经验。如果你想更快地完成工作,就让更多的人来工作。
在设计参与者系统时,将系统的主要部分分配给具有不同职责的参与者是一个很好的原则。例如,在 ETL 管道中,可能有:
假设解析器 actor 使用了一个辅助方法。这个方法是否应该封装在它自己的 actor 中取决于该方法的作用。将任务分解为子任务是个好主意,但在某些时候,您必须确定任务太“小”——太小而不能成为它自己的演员。
回到人的比喻,让我们将管道中的每个阶段想象成一个人。让我们假设解析器人员需要一支削尖的铅笔来完成他的工作,并且当前解析器自己得到铅笔。雇佣一个卑微的实习生(从 Wyatt 的书中借用另一个插图),其唯一的工作是削铅笔并在需要时将其交给解析人员是否有意义?如果有大量的数据流入,不雇佣实习生,雇佣更多的解析人员就够了吗?为 10 个解析器配备 30 个削铅笔实习生可能效率不高。换句话说,我们可能不需要根据解析器的数量独立调整实习生的数量。如果我们确实需要这样做,那将表明实习生'
总结一下这个主观的思考:
辅助方法应该在哪里?
几个想法:
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句