2011-12-14 88 views
3

我正在考虑一个Java设计,我想要一个字符串对象,但比类String更类型安全。这是因为我有许多用于Hibernate的'POJO'对象,代表我的数据库表。每个类都有大量代表类的属性公共静态字段,即:类型安全扩展字符串 - Java

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放在的位置,那么这个类型就是这种可能的设计模式。 (虽然现在我提到它,但是Enums可能是要走的路。)

回答

3

对于Java 1.5及更高版本,只需使用enum type即可。

对于Java 1.4及更低版本,请使用typesafe enum pattern。例如。

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

为什么使用这种模式,而不是使用实际的枚举?这种模式与JDK 1.4相关,但它不再相关。 –

+0

我要回应上面的评论,因为就书面而言,在使用枚举方面我没有看到任何优势。 –

+0

好的,我同意,回答更新。 – donturner

2

我会使用枚举。这样你就可以进行编译时检查。

如果你的字符串真的有一个很好的相当标准的命名约定,比如你的例子中的“column”+“One”,“Two”等等,你可以通过组合前缀的枚举来节省很多工作用一个int作为后缀。因此,创建一个类或实用程序方法,为该前缀获取枚举,例如COLUMN,并将它与一个int(如2)结合,以产生“columnTwo”。

另一种方法可能是让您的代码像parseAndSet一样验证传入的字符串是否符合数组或合法字符串的集合,或者可能是正则表达式,并引发IllegalArgumentException。你会得到运行时检查,如果你有良好的单元测试,这可以工作。

编辑ADDED

@ sethupathi.t在他回答一个不错的主意 - 在某些情况下,可能最好使第二个参数(我将使用一个int)也是一个枚举。

1

据我所知,有两种合理的方法可以做你想做的事情。

第一种方法(也许最好的方法,如果它适合你)是使用枚举,如另一个答案中提到的。

第二种方式,这可能是,如果你不知道你所有的属性名的在运行时的需要,将是沿行使用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); 
    } 

} 

这不是在它的理想不提供您的财产名称的真正的类型安全,但它确实确保了它们的有效性。

2

枚举(枚举)是一个更好的主意,上面提到的场景。

如:

枚举PROP_FIELD_COLUMN { columnOne,columnTwo等 }

1

我有第二枚举答案。

但是,对于您的问题,更直接的回答是Java为类字符串对象提供了接口,java.lang.CharSequence,并且标准Java库的很多部分已更新为在适当情况下接受CharSequence。然而,这不会给你想要的行为,也就是让你的类表现为String的子类型。