为了避免繁琐的转型,为了获得类型安全的各种优势,我们也可以选择为每种不同的消息创建独立的类型。不过由于一个Actor往往会应对各种消息,因此在.NET环境中,往往我们需要把消息类型定义为object。如果使用ActorLite来演示的话,代码可能是这样的:
ActorLite的演示
- class Person : Actor<object>
- {
- protected override void Receive(object message)
- {
- if (message is ChatMessage)
- {
- ChatMessage chatMsg = (ChatMessage)message;
- Person another = chatMsg.Another;
- Topic topic = chatMsg.Topic;
- // ...
- }
- else if (message is EatMessage)
- {
- EatMessage eatMsg = (EatMessage)message;
- Restaurant restaurant = eatMsg.Restaurant;
- // ...
- }
- else if (message is WorkMessage)
- {
- WorkMessage workMsg = (WorkMessage)message;
- Person reportTo = workMsg.ReportTo;
- Job job = workMsg.Job;
- // ...
- }
- }
- }
图示如下:
在Actorlite演示中,使用if…else来进行逻辑分支判断还是必要的,不过我们这里使用了静态类型代替了Magic String(当然在使用Tag Message时也可以使用常量)的判断,同时危险而麻烦的类型转换操作也减少的。与Tag Message相比,这种做法获得了一定的类型安全优势,可以得到编译器的静态检查,做起重构来也有了依据。不过他也有比较明显的缺陷,那就是需要构建大量的消息类型。要知道消息类型的数量很可能是Actor类型数量的几倍,每种消息类型还包含着多个属性,构造函数接受参数,然后在构造函数里设置属性……这种做法对复杂性的提升还是较为可观的,有时候会感觉还不如使用简单的Tag Message。
【编辑推荐】