Compartir a través de

Reliable Actors 框架中的多态性技术

Reliable Actors 框架允许使用许多在面向对象的设计中使用的相同技术来生成执行组件。 其中一种技术是多态性技术,它允许类型和接口从多个通用父类中继承。 Reliable Actors 框架中的继承通常遵循 .NET 模型,并会受到一些附加限制。 在 Java/Linux 中,它遵循 Java 模型。

接口

Reliable Actors 框架要求至少定义一个要由执行组件类型实现的接口。 此接口用于生成代理类,客户端可以使用此代理类与执行组件进行通信。 只要由执行组件类型实现的每个接口及其所有父接口最终派生自 IActor(C#) 或 Actor(Java),就可以从其他接口继承接口。 IActor(C#) 和 Actor(Java) 是平台定义的基接口,分别用于 .NET 和 Java 框架中的执行组件。 因此,使用形状的经典多态性示例可能如下所示:

Interface hierarchy for shape actors

类型

还可以创建执行组件类型的层次结构,这些类型派生自由平台提供的执行组件基类。 如果是形状,则可能具有一个 Shape(C#) 或 ShapeImpl(Java) 基类型:

public abstract class Shape : Actor, IShape
{
    public abstract Task<int> GetVerticeCount();

    public abstract Task<double> GetAreaAsync();
}
public abstract class ShapeImpl extends FabricActor implements Shape
{
    public abstract CompletableFuture<int> getVerticeCount();

    public abstract CompletableFuture<double> getAreaAsync();
}

Shape(C#) 或 ShapeImpl(Java) 的子类型可以重写基类型的方法。

[ActorService(Name = "Circle")]
[StatePersistence(StatePersistence.Persisted)]
public class Circle : Shape, ICircle
{
    public override Task<int> GetVerticeCount()
    {
        return Task.FromResult(0);
    }

    public override async Task<double> GetAreaAsync()
    {
        CircleState state = await this.StateManager.GetStateAsync<CircleState>("circle");

        return Math.PI *
            state.Radius *
            state.Radius;
    }
}
@ActorServiceAttribute(name = "Circle")
@StatePersistenceAttribute(statePersistence = StatePersistence.Persisted)
public class Circle extends ShapeImpl implements Circle
{
    @Override
    public CompletableFuture<Integer> getVerticeCount()
    {
        return CompletableFuture.completedFuture(0);
    }

    @Override
    public CompletableFuture<Double> getAreaAsync()
    {
        return (this.stateManager().getStateAsync<CircleState>("circle").thenApply(state->{
          return Math.PI * state.radius * state.radius;
        }));
    }
}

请注意执行组件类型上的 ActorService 属性。 此属性告知 Reliable Actor 框架,它应自动创建用于托管此类型的执行组件的服务。 在某些情况下,建议创建仅用于与子类型共享功能,并且始终不会用于实例化具体的执行组件的基类型。 在这些情况下,应使用 abstract 关键字表示始终不会基于此类型创建执行组件。

后续步骤