我正在开发串行数据协议(protocol)的解析器。我有一个总体 Packet
类,几个子类,例如 CommandPacket
和 StatusPacket
,然后每个子类都有一些子类:
- 数据包
- 命令包
- 命令类型A
- 命令类型B
- 状态数据包
- 状态类型A
- 状态类型B
Packet
类有一个静态方法,用于从缓冲区中取出数据,如果它表示有效数据包,则返回 Packet
类的新实例(已实例化)以及必要的数据。
现在,这就是我的问题所在。我希望能够返回最具体类型的数据包。为了实现这一点,我创建了一个静态 .isValid()
方法,该方法在子类上被重写。我的想法是,我可以循环遍历每种类型的特定数据包(CommandTypeA
、CommandTypeB
、StatusTypeA
、StatusTypeB
、等)调用 .isValid()
直到其中一个返回 TRUE
。那时,我将返回该特定数据包类型的新实例。
虽然我当然可以直接创建此方法,但如何考虑尚未添加到我的项目中的数据包类型?我希望将来有人能够扩展我的类,而无需修改原始的 Packet
类。
我已经考虑过为此利用反射,但我避免了它,因为这些方法将为收到的每个数据包调用,并且必须高效。
关于如何重新设计我的设计模式有什么想法吗?
虽然我认为这与讨论完全无关,但我是在 VB.NET 中这样做的。这里也发布了一个类似(但不完全相同)的问题:Java - subclass validation design pattern
最佳答案
根据评论和 MarkJ 的引导,这里有一个建议(最终基于接口(interface)而不是属性来进行更强的类型检查):
public interface IPacketValidator
{
bool IsPacketValid( Packet packet );
Type PacketType { get; }
}
public class ValidatorsRegistry
{
private List<IPacketValidator> m_validatorsList;
private static ValidatorsRegistry m_Instance = new ValidatorsRegistry();
public static ValidatorsRegistry Instance { get { return m_Instance; } }
private ValidatorsRegistry()
{
InitValidatorsRegistry();
}
private void InitValidatorsRegistry()
{
m_validatorsList = new List<IPacketValidator>();
Type iPacketValidatorType = typeof( IPacketValidator );
foreach ( Assembly asm in AppDomain.CurrentDomain.GetAssemblies() )
{
foreach ( Type type in asm.GetTypes() )
{
if ( iPacketValidatorType.IsAssignableFrom( type ) && type != iPacketValidatorType )
{
IPacketValidator validator = (IPacketValidator)Activator.CreateInstance(type);
m_validatorsList.Add( validator );
}
}
}
}
public Type GetSpecificPacketType(Packet packet)
{
Type packetType = typeof( Packet );
foreach ( IPacketValidator validator in m_validatorsList )
{
if ( validator.IsPacketValid( packet ) )
{
packetType = validator.PacketType;
break;
}
}
return packetType;
}
}
关于.net - TypeOf子类的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9559283/