我正在考虑如何编写可扩展的节点类方法。目前,树结构中的每个节点都必须实现一种返回节点类型的方法(当前是枚举,它定义了如何根据节点的类型对磁盘上的节点进行序列化和反序列化)。如果用户想要使用框架并定义和实现其他节点类型,我们需要一些可扩展性。
我考虑过添加一个接口(可扩展的枚举模式)并使用像
这样的想法 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;
}
用于ElementNode(XML)和实现IKind的枚举ENode。此外,它不允许打开某种节点,这种节点似乎是一个杀手级的参数,因为人们可能不希望每次都写一个访问者实现。
目前的实施只是:
@Override
public ENode getKind() {
return ENode.ELEMENT_KIND;
}
我目前正在编写一个简单的树状结构PathSynopsis,因此使用我不想添加到核心节点的PathNodes。
BTW:以某种方式可以返回任何类型的枚举(值)与switch语句一起使用吗?......因为无法启用Enum。也许返回一个用于序列化/反序列化的简单字节值也可以使用,但它有点难看:
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带来可能性,并且实施者必须确保实现中没有字节值相同。
答案 0 :(得分:4)
当我写枚举时,它们通常构成一个封闭的集合。如果他们必须充满活力,我不会走那条路。我更倾向于考虑共同的接口和多态性。