我正在考虑如何编写一种可扩展的节点类方法。目前,树结构中的每个节点都必须实现一个返回节点类型的方法(当前是一个枚举,它定义了如何根据节点的类型对磁盘上的节点进行序列化和反序列化)。如果用户想要使用框架并定义和实现其他节点类型,我们需要一些可扩展性。
我考虑过添加一个接口(可扩展枚举模式)并使用 somethink like
public interface IKind
并在节点界面中使用类似public <E extends Enum<E> & IKind> E getKind() {...}
. 但是我什至不确定这是否可以:
@Override
public <T extends Enum<T> & IKind> T getKind() {
return (T)ENode.ELEMENT_KIND;
}
用于实现 IKind 的 ElementNode (XML) 和枚举 ENode。此外,它不允许打开那种似乎是一个杀手论点的节点,因为人们可能不想每次都编写访问者实现。
当前的实现很简单:
@Override
public ENode getKind() {
return ENode.ELEMENT_KIND;
}
我目前正在编写树结构的简单 PathSynopsis,因此使用我不想添加到核心节点的 PathNodes。
顺便说一句:是否有可能以某种方式返回任何类型的枚举(值)以与 switch 语句一起使用?...因为无法打开枚举。
也许返回一个用于序列化/反序列化的简单字节值也可以使用,但它有点难看:
switch (ENode.getKind(pNewRtx.getNode().getKind()))
和
public enum ENode implements IKind {
ELEMENT((byte) 0, ElementNode.class) {
serialize(...) {...}
deserialize(...) {...}
}
...
/** Mapping of keys -> nodes. */
private static final Map<Byte, ENode> INSTANCEFORID = new HashMap<>();
/** Mapping of class -> nodes. */
private static final Map<Class<? extends INode>, ENode> INSTANCEFORCLASS = new HashMap<>();
static {
for (final ENode node : values()) {
INSTANCEFORID.put(node.mId, node);
INSTANCEFORCLASS.put(node.mClass, node);
}
}
...
/**
* Get the related node based on the identifier.
*
* @param pId
* the identifier for the node
* @return the related node value
*/
public static ENode getKind(final byte pId) {
return INSTANCEFORID.get(pId);
}
和
public interface IKind {
/**
* Deserializing a node using a {@link ITTSource}.
*
* @param pSource
* input source
* @return a {@link INode} instance
*/
INode deserialize(final ITTSource pSource);
/**
* Serializing a node from a {@link ITTSink}.
*
* @param pSink
* where the data should be serialized to
* @param pToSerialize
* the node to serialize
*/
void serialize(final ITTSink pSink, final INode pToSerialize);
/**
* Get the nodeKind.
*
* @return the unique kind
*/
byte getKind();
}
然而,这甚至会引入 NPE 的可能性,并且实现者必须确保在实现之间没有字节值是相同的。