Another example of virtual calls vs. type-checking

折月煮酒 提交于 2019-12-06 09:06:09

Well, considering that you probably don't want much additional logic inside each packet, you can accomplish it through Double Dispatch.

In that case, I'd probably create an interface, such as:

public interface IPacketEvents 
{
    void On(Foo foo);
    void On(Bar bar);
}

I'm assuming you have a base class for all packets. In it I would declare:

public abstract void RaiseUsing(IPacketEvents events);

And each subclass of package would implement the following:

public override void RaiseUsing(IPacketEvents events) 
{
    events.On(this);
}

You could either have a new class implement the IPacketEvents or that same class from where you call the factory could implement it. In that second case, your call would end up as:

OnDataReceived:
    RcvPacket p = RcvPacket.ReadPacket(comport);   // Call factory method
    p.RaiseUsing(this);

Using this type of dispatch, what you get, is that each type, calls the corresponding method, because it "knows" which one to call. It may confuse a bit that I used the same "On" name for all methods, but that's not entirely necessary. They could be OnFoo() and OnBar().

This type of behavior is also used in the Visitor pattern.

The only way I can think of is to move the implementation of OnFoo and OnBar to the RcvPacketFoo and RcvPacketBar classes.

public class RcvPacket{
     public abstract void On(RcvPacketHandler eh);
}
public class RcvPacketFoo : RcvPacket
{
     public override void On(RcvPacketHandler eh){eh.OnFoo();} //OnFoo implemenation
}

public class RcvPacketBar : RcvPacket
{
     public override void On(RcvPacketHandler eh){eh.OnBar();} //OnBar implemenation
}
//Update following your comment:
public class RcvPacketHandler
{
public void OnFoo(){}
public void OnBar(){}
//....
OnDataReceived:
    RcvPacket p = RcvPacket.ReadPacket(comport);   // Call factory method
    p.On(this);
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!