我构建了一个继承层次结构,其中一堆具体类继承自抽象超类A。A具有一个强制属性 Stringa和一个可选的 Mapb和 xml 模型规范的模型元素。和a中可能的键值对b都是 jaxp.NamedNodeList 的一部分。a因此,要设置和 的值,b我总是需要遍历列表并检查当前属性是否具有名称“id”,并分别设置 的值a或将键值对添加到b. 显然有人想将其外包给工厂方法等。但是,在抽象超类中实现静态工厂方法A显然是不够的,因为通过返回 A 的新实例,我需要在使用工厂方法创建它时将实例化向下转换为具体元素。所以我想出了一个使用反射的解决方案,但我真的很不安全,因为没有更简单的方法来解决一个看起来如此普遍的问题。
有没有更简单的解决方案?
这是我的工厂模式,ClassCastException当将 A 向下转换为 B 时,会产生这样的结果SubclassB b = (SubclassB) AbstractSuperClassA.createWith(attributes);:
public static AbstractSuperClassA createWith(NamedNodeMap attributes) {
Map<String, String> attributeMap = new HashMap<>();
String a= null;
for (int i = 0; i < attributes.getLength(); i++) {
if (attributes.item(i).getNodeName().equals("id")) {
a = attributes.item(i).getNodeValue();
}
attributeMap.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());
}
if (a == null) {
// throw RuntimeException
}
return new AbstractSuperClassA (identifier, attributeMap);
}
这是通用的反射实现:
public static <T extends AbstractSuperClassA > T init(NamedNodeMap attributes, Class<T> clazz) {
Map<String, String> attributeMap = new HashMap<>();
String a= null;
for (int i = 0; i < attributes.getLength(); i++) {
if (attributes.item(i).getNodeName().equals("id")) {
a = attributes.item(i).getNodeValue();
}
attributeMap.put(attributes.item(i).getNodeName(), attributes.item(i).getNodeValue());
}
if (a== null) {
// throw RuntimeException
}
try {
Constructor<T> constructor = clazz.getConstructor(String.class);
T newElement = constructor.newInstance(a);
newElement.setAttributes(attributeMap);
return newElement;
} catch (NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) {
log.error(e.getMessage(), e);
}
return null;
}
蓝山帝景
相关分类