我有一个类,它只包含静态成员变量和静态方法。本质上,它充当一个通用工具类。
一个仅包含静态成员变量和静态方法的类是不是不好的实践?
不,我完全不认为是这样。将一个类充满实例方法但实际上并不依赖于特定实例更加糟糕的做法。将它们作为静态方法告诉用户它们的预期使用方式。此外,这种方式可以避免不必要的实例化。
编辑:事后想一想,总的来说,我认为最好避免仅仅因为某个编程语言特性存在而使用它,或者因为你认为这是“Java的做法”。我记得我的第一份工作中有一个类充满了静态实用方法,其中一位资深程序员告诉我,通过让我所有的方法都是“全局”的,我没有充分利用Java的OO特性。她在团队里待不到6个月。
Math
类是一个主要例子。听起来很合理。
注意:这样做的类通常有一个私有的无参构造函数,这样如果程序员尝试创建静态类的实例,编译器就会产生错误。
对我而言,静态方法不会引起太多担忧(除了测试)。
总体而言,静态成员是一个问题。例如,如果您的应用程序被集群化了怎么办?启动时间呢——正在进行什么样的初始化?要考虑这些问题及更多问题,请查看Gilad Bracha的这篇文章。
这是完全合理的。事实上,在C#中,您可以使用static关键字定义一个类,专门用于此目的。
不要过度使用它。请注意,java.lang.Math类仅涉及数学函数。您可能还有一个名为StringUtilities的类,其中包含常见的字符串处理函数,这些函数不在标准API中。但是,如果您的类命名为Utilities,那么这就是您需要将其拆分的提示。
import static java.lang.Math.PI;
import static java.lang.Math.pow;
import static java.lang.Math.*;
虽然我同意这听起来像是一个合理的解决方案(正如其他人已经提到的),但你可能需要考虑一下,从设计的角度来看,为什么你要为“实用”目的而设立一个类。这些功能是否真正通用于整个系统,还是它们实际上与你架构中某些特定类别的对象有关。
只要你已经考虑过这个问题,我认为你的解决方案没有问题。
根据面向对象设计的严格解释,应该避免使用实用类。
问题在于,如果您遵循严格的解释,那么您需要将类强制转换为某种对象才能完成许多事情。
即使是Java设计师也会创建实用类(例如java.lang.Math)
您的选择包括:
double distance = Math.sqrt(x*x + y*y); //using static utility class
对比:
RootCalculator mySquareRooter = new SquareRootCalculator();
mySquareRooter.setValueToRoot(x*x + y*y);
double distance;
try{
distance = mySquareRooter.getRoot();
}
catch InvalidParameterException ......yadda yadda yadda.
即使我们避免了冗长的方法,我们仍然可能会得到:
Mathemetician myMathD00d = new Mathemetician()
double distance = myMathD00d.sqrt(...);
java.lang.Math
是一个完全由静态方法组成的类,其构造函数为private
(无法实例化)。 - Asaph