我的java代码中有一部分是我从库中扩展一个类,我还没写过。
@override
public Object getPropertyValue(Object id) {
if(id.equals(model.PROPERTY_RENAME))
model.setName((String)value);
else if(id.equals(model.PROPERTY_COLOUR))
model.setColor((Color)value);
}
现在,在这种情况下,我应该如何修改此代码以使其可伸缩。将会有更多属性,如位置,维度等。现在,此模型是抽象类AbsModel
的实例。
因此,实现AbsModel
的每个类都有不同的属性。所以类架构应该存在,所以无论我添加多少个模型类,这部分代码都保持不变。
答案 0 :(得分:1)
当调用此方法(getPropertyValue)时,您似乎希望对模型执行某些操作。我将在如下定义的接口ModelOperation上创建一个id的Map:
public interface ModelOperation {
void operate(Object value);
}
然后地图定义如下:
map.put(model.PROPERTY_RENAME, new RenameOperation(model));
您的扩展程序类将如下所示:
@Override
public Object getPropertyValue(Object id) {
map.get(id).operate(model);
// etc...
}
例如,RenameOperation将定义如下:
public class RenameOperation implements ModelOperation {
public RenameOperation(Model model) {
// etc...
}
public void operate(Object value) {
model.setName((String)value);
}
}
这允许您支持任意数量的模型操作,这意味着您不必更改必须编写的扩展类。以上只是一个大纲。您可以在ModelOperation实现上使用泛型来避免在每个实现中转换值。
答案 1 :(得分:0)
常见的方法是使用像
这样的反射public Object getValue(IdType id) {
Method getter = model.getClass().getMethod("get" + id);
return getter.invoke(model); // throws Exceptions.
}
OR
public void setValue(IdType id, Object value) {
Method setter = model.getClass().getMethod("set" + id, value.getClass());
setter.invoke(model, value); // throws Exceptions.
}
答案 2 :(得分:0)
如果您可以依靠某些命名来帮助指导您,我想这里的答案可能就是答案。
这不会很好,但想法是你有一个方法可以反映出类型并查找适当的方法。代码belwo
public Object setPropertyValue(Object id) {
String className = id.getClass().getSimpleName();
// Hope that the method is called set<CLASS> and takes a single parameter that is the class
Method method = model.class.getMethod("set" + className, id.getClass());
// Invoke the method (TODO deal with all of the exceptions)
method.invoke(model, id);
}
答案 3 :(得分:0)
有多种方法可以做到这一点 - 虽然这取决于“可扩展”是什么意思(能够应对每秒的大量请求或能够处理大量属性?):
答案 4 :(得分:0)
由于在Java函数中不是一等公民,所以“好”的路径会非常笨拙:定义一个枚举,每个常量上面有一个值(即对于每个属性),以及一个虚拟方法,例如: update(Object value
,然后覆盖每个枚举中的方法以更新相应的属性。如果可以,请将常量PROPERTY_RENAME
等自己重新定义为枚举。这仍然导致代码膨胀。
另一种方法是使用反射。如果可以使用与要更新的属性名称相同的ID,则只需调用属性的setter(如其他答案中所示)。否则,您可能需要引入从ids到属性名称的映射。
答案 5 :(得分:0)
不使用反射的版本,调用基类的实现:
public Object getValue(Object id) {
Object ret = super.getValue(id);
if (ret == null) {
// Subclass specific properties
}
return ret;
}
答案 6 :(得分:0)
我通过创建界面解决了这个问题。所以代码是。
public interface IModel
{
public void setProperty(String propertyName);
}
其他课程
public class HelloModel implements IModel
{
public void setProperty(String propertyName)
{ code for handling the properties goes here ... }
}
所以在这种情况下,每个类都必须处理它自己的属性设置器。 这是处理抽象的最佳方法吗?我认为这个模型非常具有可扩展性......