问题
我发誓,每次我把它捣烂成我的大脑,我应该使用虚拟电话与类型检查(如:
if (obj is Foo)
...
else if (obj is Bar)
...
......我拿出另一个例子,我不知道如何实现前者。
我采取了一个串行端口的打包协议。 一些伪代码解释最好:
OnDataReceived:
RcvPacket p = RcvPacket.ReadPacket(comport); // Call factory method
if (p is RcvPacketFoo)
OnFoo();
if (p is RcvPacketBar)
OnBar();
OnFoo:
raise Foo event
OnBar:
raise Bar event
基本上,ReadPacket是在基类 ,其确定所接收分组的类型工厂方法 ,并传递缓冲到正确的派生类型构造函数。 在此之后,我需要提高的情况下,根据数据包的类型。 我怎样才能做到这一点,而不使用的is
运营商? 是我的方法声音/理智?
解
该访问者模式 ,当然! 感谢巴勃罗·罗密欧 。
在这种情况下,我做了控制器,即调用工厂方法,是游客。 我的结果:
public interface IPacketHandler {
void Handle(FooPacket p);
void Handle(BarPacket p);
}
public class Controller : IPacketHandler {
OnDataReceived() {
RcvPacket p = RcvPacket.ReadPacket(comport); // Call factory method
p.Handle(this); // *** Virtual Call: The first dispatch ***
}
// Note the use of explicit interface implementation here.
IPacketHandler.Handle(FooPacket p) {
OnFoo();
}
IPacketHandler.Handle(BarPacket p) {
OnBar();
}
}
public abstract class RcvPacket {
public static RcvPacket ReadPacket(...) { ... } // Factory method
public void Handle(IPacketHandler handler);
}
public class FooPacket : RcvPacket {
public override void Handle(IPacketHandler handler) {
handler.Handle(this); // *** Overloaded call: The second dispatch ***
}
}
public class BarPacket : RcvPacket {
public override void Handle(IPacketHandler handler) {
handler.Handle(this); // *** Overloaded call: The second dispatch ***
}
}
这里的有趣的事情,是通过明确实现访问者接口方面, Handle
通话基本上是隐藏起来。 从MSDN :
实现接口的类可以显式实现该接口的成员。 当一个成员被显式实现,它不能通过类实例访问,而只能通过接口的实例。