Akka for Java,如何使用带有泛型的Actor

5 java generics akka

在您的应用程序中使用异步流程时,Akka似乎是一个很好的框架/概念.我正在为我的一个项目学习Akka,我想知道如何正确设计Actors.

想象一下下面的演员:

public class SampleActor extends UntypedActor {
    private final LoggingAdapter log = 
            Logging.getLogger(getContext().system(), this);

    @Override
    public void onReceive(final Object message) throws Exception {
        if (message instanceof SomeType) {
            SomeType someType = ((SomeType) message);
            // Handle SomeType
        } else if (message instance SomeOtherType) {
            SomeOtherType someOtherType = ((SomeOtherType) message);
            // Handle SomeOtherType
        } else {
            unhandled(message);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

上面的代码是一种常见的模式,例如在Akka文档中描述的.

上面的模式对我来说似乎是一种老派,有一堆instanceof检查和演员处理Object.是否有另一种首选方法(如某些基类,您可以指定您感兴趣的类型)或类似方法.

我可以看到的一个替代方案是你继承一个通用的演员,例如:

public class SampleActor extends GenericActor<SomeType> {
    public void onReceive(final SomeType someType) throws Exception {
        // Do stuff
    }
}
Run Code Online (Sandbox Code Playgroud)

那么,与演员合作的最佳做​​法是什么.是延伸UntypedActor还是我错过了什么?

hic*_*our 1

首先看一下为 Scala 模式匹配设计的UntypedActorand方法契约onReceive方法契约,这种简化的设计有一些美感。

使用 Java,您需要进行某种权衡。您可以使用您的自定义实现Visitor,但这会增加不必要的工作。

最好的方法是使用AbstractActor它的PartialFunction<Object, BoxedUnit> receive()方法,并由您自己的抽象支持。

public abstract class AbstractAggregateRegistryActor extends AbstractActor {

    @Override
    public PartialFunction<Object, BoxedUnit> receive() {
        return ReceiveBuilder.
                match(Protocol.AbstractComponentRegister.class, 
                                      this::handleRegistration).
                match(Protocol.AbstractComponentDeregister.class,
                                      this::handleDeregistration).
                match(Protocol.AbstractComponentRegistryRequest.class,
                                      this::handleRegistryRequest).
                matchAny(this::unhandled).build();
    }


    private void handleRegistration(Protocol.AbstractComponentRegister
                                    componentRegister) {
        .....
    }

    private void handleDeregistration(Protocol.AbstractComponentDeregister
                                      componentDeregister) {
        ...
    }

    protected abstract <T extends Protocol.AbstractComponentRegistryRequest> 
                         void handleRegistryRequest(T registryRequest);


    @Override
    public void unhandled(Object message) {
        log.warning("Unhandled message {} in registry.", message);
    }
}
Run Code Online (Sandbox Code Playgroud)