技术开发 频道

C# Actor消息执行:阶段性总结

    接口、协议及消息

    消息,其实是两个Actor之间定下的协议,一个Actor可以实现多种协议。这样的对应关系使人联想到.NET中的接口。因此我们可以使Actor实现某个接口,一条消息其实就是使用“委托”来告诉Actor该做什么事情。一个“委托”对象也可以自然地携带执行时所用的数据。这似乎满足我们的要求。使用这种方式来实现的消息执行大概是这样的:

interface IPersonMessageHandler
{
void Chat(Person another, Topic topic);
void Eat(Restaurant restaurant);
void Work(Person reportTo, Job job);
}

class Person : Actor<Action<IPersonMessageHandler>>, IPersonMessageHandler
{
protected override void Receive(Action<IPersonMessageHandler> message)
{
message(this);
}

#region IPersonMessageHandler Members

void IPersonMessageHandler.Chat(Person another, Topic topic) { ... }

void IPersonMessageHandler.Eat(Restaurant restaurant) { ... }

void IPersonMessageHandler.Work(Person reportTo, Job job) { ... }

#endregion
}
 

    图示如下:

 

     使用这种方式似乎带来的许多好处,例如我们使用接口这个非常轻量级的特性实现了消息,无须编写额外的代码将消息转化为逻辑。此外,接口是强类型的,适合编译期检查,易于重构和单元测试,还为我们带来“消息组”这样一种简单的消息管理方式——似乎就是我们理想的消息执行方式啊。是啊,这是很美好的消息执行方式,但是……为什么说它“中看不中用”?

  这里带来的最大问题在于耦合地过于强烈。例如Chat消息的第一个参数是Person,表示聊天的对象。但是很可能在同一个系统中,可以聊天的对象不一定仅限于是人(Person),还可能是一个机器人(Robot);同理Work的汇报者也可能是一个记录系统。事实上,我们可能只要求Chat的目标是一个可以处理IChater消息的Actor即可,这意味着Chat方法的第一个参数的类型需要是Actor<Action<IChater>>。但是,这个Actor还需要接受其他类型的消息,如IWorkReportHandler,这又意味着它的类型需要是Actor<Action<IWorkResultHandler>>。一个Actor又如何成为两种类型?

  在实际运用中,这点无法回避,因此我们必须得变。

0
相关文章