我正在尝试实施工厂模式,但遇到了问题。我试着让我的课程变得简单。基本上我有一个基本的Packet类(PacketHeader),包含一些字段和方法。此外,我有很多派生的数据包类,如:InfoPacket1011,UsagePacket1011,InfoPacket1014,UsagePacket1014,它们都继承自PacketHeader基类。
正如您所看到的,每个数据包都有一个版本,我的目标是根据其版本处理这些数据包。所以我应该有两个派生类,一个用于1011,一个用于1014.
基类(它本身就是派生类!)看起来像这样:
public abstract class PacketHandlerBase : Engine
{
public abstract bool SendInfoPacket(int someInt, string someInput);
public abstract List<???> BuildInfoPacket(string someInput);
public abstract bool SendUsagePacket(int someInt, string someInput);
public abstract List<???> BuildUsagePacket(string someInput);
//...
//...
//...
}
我的问题是,对于BuildInfoPacket和BuildUsagePacket等方法,我必须返回该类型的List。所以在派生类中我可以:
public class PacketHandler1011 : PackerHandlerBase
{
//...
public override bool SendInfoPacket(int someInt, string someInput);
{
// code implementation
// return true or false
}
public override List<InfoPacket1011> BuildInfoPacket(string someInput);
{
// code implementation
// return List<InfoPacket1011>
}
}
public class PacketHandler1014 : PackerHandlerBase
{
//...
public override bool SendInfoPacket(int someInt, string someInput);
{
// code implementation
// return true or false
}
public override List<InfoPacket1014> BuildInfoPacket(string someInput);
{
// code implementation
// return List<InfoPacket1014>
}
}
我不知道在PacketHandlerBase类中使用什么来能够在派生类中覆盖它。我想我需要通用的方法和接口,但不知道如何处理它。
[编辑] :我修复了有关数据包继承的第一部分问题。谢谢大家的答案,我读了它们并告诉你它们是否有效。
[答案] :谢谢大家的快速回复。我通过传递List并将其强制转换为方法和调用者来解决问题。好吧,我的代码比我在这里提供的代码复杂得多,我刚刚修改完它。我也将模式改为抽象工厂,以解决其他一些问题。
非常感谢任何帮助。 提前致谢
答案 0 :(得分:3)
基类中的所有方法都应返回InfoPacketBase
以及为数据包使用创建基类,例如UsagePacketBase
,您需要查看polymorphism
public abstract class PacketHandlerBase : Engine
{
public abstract bool SendInfoPacket(int someInt, string someInput);
public abstract List<PackeHeader> BuildInfoPacket(string someInput);
public abstract bool SendUsagePacket(int someInt, string someInput);
public abstract List<PackeHeader> BuildUsagePacket(string someInput);
//...
//...
//...
}
答案 1 :(得分:1)
您实际上正在实施Abstract Factory模式,其中PackerHandlerBase
是抽象工厂,它会生成/构建抽象产品案例是InfoPacket
和UsagePacket
。 混凝土工厂是PacketHandler1011
或PacketHandler1014
。 具体产品为InfoPacket1011
或InfoPacket1014
,依此类推。
所以它应该是:
public abstract class PacketHandlerBase : Engine
{
public abstract bool SendInfoPacket(int someInt, string someInput);
public abstract List<InfoPacket> BuildInfoPacket(string someInput);
public abstract bool SendUsagePacket(int someInt, string someInput);
public abstract List<UsagePacker> BuildUsagePacket(string someInput);
//...
}
public class InfoPacket1014 : InfoPacket
{
///...
}
public class PacketHandler1011 : PackerHandlerBase
{
//...
public override List<InfoPacket> BuildInfoPacket(string someInput);
{
// code implementation
return new List<InfoPacket> { new InfoPacket1011(), ... };
}
}
答案 2 :(得分:0)
以下是使用它的通用方法示例: 在类型约束中使用您的实体,如:
where T : InfoPacketBase
以及派生类方法:List<InfoPacket1011>
;
abstract class A
{
public abstract List<T> BuildInfoPacket<T>(string someInput) where T : new();
}
class B : A
{
public override List<T> BuildInfoPacket<T>(string someInput)
{
// code implementation
return new List<T> { new T() };
}
public void Test()
{
BuildInfoPacket<object>("test");
}
}
答案 3 :(得分:0)
怎么样:
public abstract class PacketHandlerBase<TInfoPacket, TUsagePacket> : Engine
where TInfoPacket : IInfoPacket
where TUsagePacket : IUsagePacket
{
public abstract bool SendInfoPacket(int someInt, string someInput);
public abstract List<TInfoPacket> BuildInfoPacket(string someInput);
public abstract bool SendUsagePacket(int someInt, string someInput);
public abstract List<TUsagePacket > BuildUsagePacket(string someInput);
}
确保您的信息包类实现了一个IInfoPacket接口。例如:
public InfoPacket1101 : PacketHeader, IInfoPacket
{
...
}
类似地,所有使用包类都实现了IUsagePacket。然后你可以编写一个给定版本的数据包处理程序,如下所示:
public class PacketHandler1011 : PackerHandlerBase<InfoPacket1101, UsagePacket1101>
{
...
}
我认为这是首选解决方案,因为这意味着您可以对返回的对象有更强的保证。如果只有一个基类,就像在当前接受的答案中一样,你不能在没有强制转换的情况下对BuildInfoPacket返回的对象调用任何“信息包”特定的方法。与使用数据包类似。在此解决方案中,IInfoPacket接口可以具有您无需强制转换即可调用的方法。
答案 4 :(得分:0)
如果您不理解它们并且完全了解它们的缺点,请不要使用泛型。在这种情况下,您只需返回IEnumerable<PacketHeader>
并让多态性解析为休息。
public abstract class PacketHandlerBase : Engine
{
public abstract bool SendInfoPacket(int someInt, string someInput);
public abstract IEnumerable<PacketHeader> BuildInfoPacket(string someInput);
public abstract bool SendUsagePacket(int someInt, string someInput);
public abstract IEnumerable<PacketHeader> BuildUsagePacket(string someInput);
//...
//...
//...
}
public class PacketHandler1011 : PackerHandlerBase
{
//...
public override bool SendInfoPacket(int someInt, string someInput);
{
// code implementation
// return true or false
}
public override IEnumerable<PacketHeader> BuildInfoPacket(string someInput);
{
yield return new InfoPacket1011(..)
// code implementation
// return List<InfoPacket1011>
}
}