我正在使用Java构建内容管理系统,我有一个表示实体的类,以及一个在实体中表达字段的类。
目前我的Field类是String的数组列表,用于存储所有值。
我的班级看起来像这样:
public class Field implements Serializable {
private UUID key;
private String name;
private ArrayList<String> values;
private Integer maxValues;
private ValueType type;
private String code;
public enum ValueType {
INT,
VARCHAR,
DATE,
BOOLEAN
}
public void addValue(String value){
if (this.values.size() < this.maxValues){
this.values.add(value);
}
}
public ArrayList<String> getValues(){
return this.values;
}
}
我想存储String,Integer,Floats和Dates,我想我可以在输入时键入检查值,并使用单独的方法将值作为正确的类型。
public ArrayList<Integer> getIntegerValues(){
ArrayList<Integer> integerValues = new ArrayList<Integer>();
values.forEach(
(v) -> {
Integer intValue = Integer.parseInt(v);
integerValues.add(intValue);
}
);
return integerValues;
}
我认为这样可行,但它不是一个很好的解决方案,因为使用这个类时你必须选择正确的函数来获取类型。如果只有一个函数可以返回正确的版本,那就太好了。
有没有人有任何想法我怎么能写得更好。
答案 0 :(得分:1)
以下是如何使用泛型的示例:
public class Field<T> implements Serializable {
private UUID key;
private String name;
private ArrayList<T> values;
private Integer maxValues;
private String code;
public void addValue(T value) {
if (this.values.size() < this.maxValues){
this.values.add(value);
}
}
public ArrayList<T> getValues(){
return this.values;
}
}
答案 1 :(得分:1)
更多的另一种观点:如果你得出结论,仿制药在这里没有帮助你 - 你仍然应该不使用枚举来做这类事情。
枚举的问题是:它们对于#34;模型&#34;非常有用。将来改变的可能性很小。因为通常会发生以下情况:对于您拥有的每个枚举,您将创建开关语句;为了实现不同的枚举常量的不同行为。这可能听起来不像是一个问题,但是......当你意识到你需要添加另一个类型时。然后你必须找到所有这些开关并决定如何处理新的枚举常量。
相反,您的设计应由Open/Closed principle:打开进行更改;但关闭进行修改。在OO中,通常转换为使用抽象类,如
public abstract class ValueType {
... which has some ABSTRACT methods
... and probably some FINAL methods
抽象方法是您实现各种子类应该不同的行为的地方;最后的方法是那些&#34;修复&#34;这种行为,对于这个类的每个实例都应该是相同的。
然后你继续前进并创建特定的子类,如IntValue extends ValueType
等。
为什么这样更好?非常简单:添加一种新的ValueType意味着......创建一个新的子类 - 无需触及任何现有代码。因此,这样的设计打开进行更改(添加新类型!),但关闭进行修改(因为添加新类型不会改变其他现有类中的任何内容)。
答案 2 :(得分:0)
我对这两个答案都不是100%满意,也不是解决这个问题的正确方法,两种方式都有问题要处理。但是我意识到两个答案一起会提供一个很好的解决方案,所以感谢两者。
您的具体类将定义通用值的值。这将满足公开的关闭委托人。
public interface FieldType<T> {
void addValue(T value);
ArrayList<T> getValues();
}
public abstract class Field<T> implements FieldType<T>, Serializable {
private UUID key;
private String name;
protected ArrayList<T> values;
private Integer maxValues;
private String code;
public abstract void addValues();
public ArrayList<T> getValues(){
return this.values;
}
}
public class FloatField extends Field<Float> {
@Override
public void addValue(Float value) {
this.values.add(value);
}
@Override
public ArrayList<Float> getValues() {
return this.values;
}
}