我正在考虑使用Java中的设计,我想要一个字符串对象但是具有更多'类型安全'而不仅仅是类String
。这是因为我有许多用于Hibernate的'POJO'对象,代表我的数据库表。这些类中的每一个都有大量的公共静态字段,表示类的属性,即:
public class PersistantBean {
public static String PROP_FIELD_COLUMN_ONE="columnOne";
public static String PROP_FIELD_COLUMN_TWO="columnTwo";
// [...]
当我们需要以通用方式访问属性时,可以使用这些属性,例如代码我目前正在撰写.parseAndSet(PROP_FIELD_PRICE,"£3.00")
。
我希望能够在PROP_FIELD_...
字段中添加更强的类型,以便我可以写
public class PersistantBean {
public static PropertyName PROP_FIELD_COLUMN_ONE="columnOne";
public static PropertyName PROP_FIELD_COLUMN_TWO="columnTwo";
// [...]
对项目的其他部分进行最小的更改,
以便parseAndSet看起来像:
public void parseAndSet(PropertyName prop, String priceToParse)
基本上,我希望PropertyName
是一个类似于String的类型,除了编译器会错误,如果我试图将String
放在预期的PropertyName
时,是这样的任何设计模式都可能。
(我正在回避Enums,虽然现在我提到它,Enums可能是要走的路。)
答案 0 :(得分:3)
对于Java 1.5及更高版本,只需使用enum type。
对于Java 1.4及更低版本,请使用typesafe enum pattern。 E.g。
public class Suit {
private final String name;
public static final Suit CLUBS =new Suit("clubs");
public static final Suit DIAMONDS =new Suit("diamonds");
public static final Suit HEARTS =new Suit("hearts");
public static final Suit SPADES =new Suit("spades");
private Suit(String name){
this.name =name;
}
public String toString(){
return name;
}
}
答案 1 :(得分:2)
我会使用Enum。这样你就可以进行编译时检查。
如果您的字符串确实具有良好的相当标准的命名约定,例如“column”+“One”,“Two”等,如您的示例中所示,您可以通过组合前缀的枚举来节省大量工作后缀为int。因此,创建一个类或实用程序方法,该方法采用前缀的枚举,例如COLUMN,并将它与int(例如2)组合在一起,以产生“columnTwo”。
替代方法可能是您的代码(如parseAndSet)验证传入的String对阵数组或合法字符串集合,或者可能是正则表达式,并抛出IllegalArgumentException。你会得到运行时检查,如果你有好的单元测试,这可能会有效。
编辑添加
@ sethupathi.t在他的回答中有一个好主意 - 在某些情况下,最好使第二个参数(我使用int)也是一个枚举。
答案 2 :(得分:2)
枚举(枚举)是一个更好的主意,如上所述。
例如:
枚举PROP_FIELD_COLUMN { columnOne,columnTwo等 }
答案 3 :(得分:1)
据我所知,有两种合理的方法可以做你想做的事。
第一种方式(可能是最好的方式,如果它适用于你)是使用枚举,如另一个答案所述。
第二种方法,如果你在运行时不知道所有的PropertyName,可能是必要的,就是使用PropertyNameFactory:
public class PropertyNameFactory
{
public static PropertyName getPropertyName(String propertyName)
{
// Check validity of the propertyName against what ever rules we
// have defined (maybe valid propertyNames are read from a DB at
// startup, etc).
if (isValid(propertyName))
{
// Ideally get from a cache, but for the sake of the example
// we will create a new one...
return new PropertyName(propertyName);
}
throw new IllegalArgumentException("Invalid property name: " + propertyName);
}
}
这并不理想,因为它不能为您的属性名称提供真正的类型安全性,但它确实确保了它们的有效性。
答案 4 :(得分:1)
我必须回答Enum的答案。
但是,对于您的问题,一个更直接的答案是Java为类似String的对象java.lang.CharSequence提供了一个接口,标准Java库的许多部分已经更新,以便在适当的时候接受CharSequence。但是,这不会为您提供所需的行为,即使您的类表现为String的子类型。