我一直在考虑为我一直在研究的框架提供语法糖的方法。我想专门处理Immitable对象。
作为使用String的示例:
public final class LOWERCASE { private LOWERCASE() {} public static String string( final String STRING ) { return STRING.toLowerCase(); } }
因此,从这个例子我可以写:
String lowercaseString = LOWERCASE.string( targetString );
我发现它非常易读。
答案 0 :(得分:4)
我不认为每个方法创建一个类是个好主意。您可以改为创建一个静态方法类,命名为例如StringUtils并实现这些方法。这样你就可以打电话:
String lowerCaseString = StringUtils.lowercase(targetString);
这也可以在您输入时为您提供智能感知帮助。你的课程列表会变得太大了。即使是这个简单的例子,你也应该实现多个小写类,这样你就可以满足CulutureInfo必须考虑的环境。
我认为这不会以任何方式破坏OO原则或者设计不好。在其他语言中,例如Ruby,您可以将方法直接添加到String类中。结束的方法!表示原始对象已被修改。所有其他方法都返回修改后的副本。 Ruby on Rails框架为String类添加了一些方法,并且对于这是否是一种好技术存在争议。这绝对很方便。
答案 1 :(得分:1)
通常在不可变对象上,我会有一个方法返回对象的修改版本。因此,如果您有一些不可变集合,它可以有一个sort()方法,它返回一个已排序的新集合。但是,在您的String示例中,这是不可能的,因为您无法触及String类。
您的方法非常易读,我认为对于这样的边缘情况,完全没问题。对于你自己写的不可变对象,我在对象本身上有方法。
顺便说一下,答案 2 :(得分:1)
在我看来,这样一个工厂类的唯一要点就是该类提供了不同类型的不可变对象。
例如:
public final class Lowercase {
private Lowercase() {}
public static String string( final String string ) {
return new String( string.toLowerCase() );
}
public static Foo foo( final Foo f ) {
boolean isLowerCase = true;
return new Foo(f, isLowerCase );
}
}
否则,您应该在不可变类本身中实现您的方法,例如String Class中的toLowerCase()。
无论哪种方式,我认为这不违反任何OO原则。
答案 3 :(得分:1)
我同意Erik的观点。不可变对象应始终具有返回对象的修改版本而不是静态方法的方法。 JDK中还有一些例子:
这样做的好处是,您不需要将要修改的实例作为方法的参数传递。对于像String或Integer这样的类,我更喜欢使用包装类。然后,您可以控制何时创建此类对象(通过包装类的构造函数或类的某个方法)。如果你要使用Integer类,那么控制它就会复杂得多,因为每个人都可以创建它的实例。
另一方面,你的例子被认为是一些实用程序类,如apache commons-lang包的StringUtils。只是看看这个,因为我认为你想创造这样的东西。 (不要重新发明轮子)
答案 4 :(得分:1)
new String()
是代码气味 - 由于String
的不变性,它几乎总是不必要。一旦String
实例具有值,该实例永远不会具有不同的值。
在以下方法中,new String()
是多余的:
public static String string( final String string ) {
return new String( string.toLowerCase() );
}
toLowerCase()
返回一个新的(不同的)String
实例 - new String()
除了导致另一个具有String
的确切值的对象创建之外,在此处没有做任何有益的事情toLowerCase()
这是一个显示概念的小Groovy脚本(我希望 - 注意,这是脚本语言下的Java):
String a = 'CamelCase'
String b = a.toLowerCase()
println "a='${a}'"
println "b='${b}'"
制造
a='CamelCase'
b='camelcase'
请注意a
没有改变 - 它是不可变的; b
是一个新的String
值。
BigDecimal.movePointLeft()
或BigDecimal
上返回BigDecimal
的任何其他方法也是如此 - 它们是新实例,原始实例保持不变。
好的,现在回答你的问题:
对Strings
执行一组在您的应用程序中执行有用目的的操作是个好主意。对String
之类的东西来说,使用工厂可能不是必需的,但可能是为了一个需要花费一些精力来构建的不同的不可变类。
如果无法扩展基类,例如String
,则描述的@ static method
类为@kgiannakakis是正常的。
否则,如果“immutable”类是应用程序的一部分,您可以访问类声明/定义,返回新实例的方法,在BigDecimal
,String
模型中,等等,会更好。这实际上是@Erik Hesselink,@ Bruno Conde和@reallyinsane所说的。