我有一个名为“DataModel”的类,它基本上是一个数据单元,可以是字符串,数字或日期,也可以是具有各种(相同)属性的布尔值。
编写此模型的最佳方法是什么?
值的类型为Object
interface DataModel {
Object getValue(); // cast to whatever is needed
int getValueType(); // uses four constants
}
有四种不同的实现“StringModel”,“NumberModel”等,每种都有自己的类型“getValue()”方法。这意味着如果您有一个DataModel,则必须转换为正确的Model才能获得该值。
interface DataModel {
int getValueType();
}
interface NumberDataModel extends DataModel {
Integer getValue();
}
...
有四种不同的方法,如果调用错误的值类型,每种方法都会抛出异常:
interface DataModel {
String getStringValue();
Integer getIntegerValue();
...
int getValueType();
}
使用泛型。这有一个缺点,我理论上可以有任何类型的任何对象...另一方面,如果T不是4种允许类型之一,我可以在构造函数中抛出IllegalStateException ...
interface DataModel<T> {
T getValue();
}
没关系。以上任何一种。 ;)
答案 0 :(得分:3)
4似乎是最好的 - 即使你不想实现任何旧类型,也没有特别的理由为什么你理论上不允许它 - 它不会干扰你正在做的任何事情。
答案 1 :(得分:2)
1就可以了。我可能会使用枚举而不是int。
我没有看到做2超过4的优点.4是通用的,你可能想要包括getValueType(),即使在通用情况下,这样你就可以让代码在运行时询问类型,通常很有用。
我不认为3是正确的方法,除非你的模型的内容支持以不同的方式检索(比如JDBC在某种程度上),但我不认为这是这种情况。
根据过去的经验,我会做4并将getValueType()添加到它。
答案 2 :(得分:2)
以上都不是。
由于您需要知道类对getValue()的结果做了一些合理的事情,因此在这种情况下,使用包含getValue()的公共接口(类似于方法)没有任何好处。
有一个带有公共部分的基类,然后继承并添加你需要的东西。您可以使用instanceof而不是getValueType(),但如果您确实需要getValueType,则可以将其作为抽象方法添加到基类中。如果你使用getValueType,我建议它返回一个枚举,而不是int。
答案 3 :(得分:2)
4是最好的答案。您将获得灵活性和便利性。
另一方面,如果你真的想限制类型,你可以使用4和2的组合。像这样:
interface DataModel<T> {
T getValue();
}
interface NumberDataModel extends DataModel<Number> {
// empty
}
class NDM implements NumberDataModel {
Number getValue() { return ... }
}
然后,您可以使DataModel接口受保护/默认。
答案 4 :(得分:0)
作为一种通用替代方法,您可以使用Class Literals as Runtime-Type Tokens并使用newInstance()
来获取数据元素的类型安全实例。这允许通过通用参数进行编译时检查,并通过isAssignableFrom()
进行运行时检查。