Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/379.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中创建无状态实用程序类的最佳实践是什么_Java_Design Patterns - Fatal编程技术网

在Java中创建无状态实用程序类的最佳实践是什么

在Java中创建无状态实用程序类的最佳实践是什么,java,design-patterns,Java,Design Patterns,在Java中创建实用程序(不包含任何状态)类的最佳实践是什么 在大多数情况下,我们最终会为此类任务创建静态方法。 其他可能的方法可以是“创建单例对象”来执行此操作 当需求是代码应易于单元测试时,设计应考虑哪些因素?我认为最常见的方法是创建静态方法。例如,请参见,甚至 此外,类应该是最终的,并且应该有一个私有构造函数,以避免继承或实例化它 无论是使用静态方法还是单例,单元测试都应该是同样的工作。在后一种情况下,您可以编写更多的代码(字符) 我知道OO纯粹主义者会争论此类类的存在,我倾向于同意他们的

在Java中创建实用程序(不包含任何状态)类的最佳实践是什么

在大多数情况下,我们最终会为此类任务创建静态方法。 其他可能的方法可以是“创建单例对象”来执行此操作


当需求是代码应易于单元测试时,设计应考虑哪些因素?

我认为最常见的方法是创建静态方法。例如,请参见,甚至

此外,类应该是最终的,并且应该有一个私有构造函数,以避免继承或实例化它

无论是使用静态方法还是单例,单元测试都应该是同样的工作。在后一种情况下,您可以编写更多的代码(字符)


我知道OO纯粹主义者会争论此类类的存在,我倾向于同意他们的观点,但添加这些类只是为了简单起见,你应该限制此类类的数量。

如果你使用Spring之类的框架,你可以创建一个带有
@Service
注释的实用类。 这将确保它是单Instance(SIngleton),并且是一种简单的注入方法,没有任何其他类需要它的方法


在任何其他情况下,我建议使用工厂模式将其设置为单例,或者在cotrast中仅使用静态方法。

静态是单例。只有当您需要使用具有不同属性/设置值的多个实用程序类变体时,才需要使用非静态方法的单例实例。例如,当您的实用程序具有某些属性(即customProperty)并且您同时需要两个不同的案例时

  • 当实用程序需要使用customProperty=value1时

  • 当实用性需要使用customProperty=value2时

  • 但它很奇怪,笨拙,不好。。。实用程序调用方可以向静态方法提供所需的属性值。
    所以,不要拘泥于此。使实用方法始终保持静态,不关心“理论”模式…:)

    如果你能纵容一下我的比喻

    您可能以前见过其中之一:

    请注意,我们称之为烤面包机。我们不称之为“面包圈”

    类似地,实用程序方法可以而且应该放在一个以特定功能命名的类中,而不是“与面包相关的杂项”

    大多数情况下,静态方法属于相关类;例如,是Integer类的静态方法,而不是理论IntegerUtil或NumberUtil类的成员

    在过去,创建单独的实用程序类的一种情况是,感兴趣的主要类是接口。这方面的一个例子是。但是,对于Java8,这不是借口,因为接口可以有静态方法和默认方法。实际上,Collections.sort(List)已经迁移到

    如果您有很多实用方法,并且您觉得它们会使相关类变得混乱,那么可以将它们放在单独的类中,而不是“BreadUtil”类中。将“util”一词放在类名(或“utils”、“utilities”、“misc”、“miscellaneous”、“general”、“shared”、“common”或“framework”)中是绝对不能接受的。给类一个有意义的名称,描述方法的用途。如果方法过于多样化,不允许使用这样的类名,则可能需要将它们拆分为多个类。(只有少数方法的小班是完全可以接受的;许多人甚至认为好的设计。)< /P> 回到Integer示例,如果您觉得方法对类造成混乱,可以创建如下新类:

    public class IntegerMath {
        private IntegerMath() { }
    
        public static int compare(int x, int y) { /* ... */ }
        public static int compareUnsigned(int x, int y) { /* ... */ }
        public static int divideUnsigned(int dividend, int divisor) { /* ... */ }
        public static int min(int a, int b) { /* ... */ }
        public static int max(int a, int b) { /* ... */ }
        public static int remainderUnsigned(int dividend, int divisor) { /* ... */ }
        public static int signum(int i) { /* ... */ }
        public static int sum(int a, int b) { /* ... */ }
        public static long toUnsignedLong(int i) { /* ... */ }
    }
    
    public class IntegerBits {
        private IntegerBits() { }
    
        public static int bitCount(int i) { /* ... */ }
        public static int highestOneBit(int i) { /* ... */ }
        public static int lowestOneBit(int i) { /* ... */ }
        public static int numberOfLeadingZeros(int i) { /* ... */ }
        public static int numberOfTrailingZeros(int i) { /* ... */ }
        public static int reverse(int i) { /* ... */ }
        public static int reverseBytes(int i) { /* ... */ }
        public static int rotateLeft(int i, int distance) { /* ... */ }
        public static int rotateRight(int i, int distance) { /* ... */ }
    }
    
    public class IntegerParser {
        private IntegerParser() { }
    
        public static int parseInt(String s) { /* ... */ }
        public static int parseInt(String s, int radix) { /* ... */ }
        public static int parseUnsignedInt(String s) { /* ... */ }
        public static int parseUnsignedInt(String s, int radix) { /* ... */ }
    }
    
    最后一个例子说明了没有静态方法可能会更好:

    public class IntegerParser {
        public IntegerParser() { this(10); }
        public IntegerParser(int radix) { /* ... */ }
    
        public int parseInt(String s) { /* ... */ }
        public int parseUnsignedInt(String s) { /* ... */ }
    }
    
    在Java中创建实用程序(不包含任何状态)类的最佳实践是什么

    在我看来,最好的方法是尽可能省略实用程序类

    实用程序类颠覆了面向对象编程的思想。当您需要一个新方法时,通常会将其添加到具有最高内聚性的类中。这意味着类保存了方法所需的大部分信息。其他信息将作为参数传递到方法中。如果参数列表太长,它通常是放错位置的方法的指示符

    很少有情况下,您确实需要一个实用程序类来为某些类型提供方法。例如

    • 如果您无法将该方法添加到源代码中,因为您不拥有它(但您可以创建一个包装器或将其子类化)
    • 如果需要附加方法的类是final,并且您不拥有源代码(例如StringUtility)
    在大多数情况下,我们最终会为此类任务创建静态方法。其他可能的方法可以是“创建单例对象”来执行此操作

    当要求代码应易于单元测试时,设计应考虑什么

    如果从单元可测试性的角度来看实用程序类,并且希望能够模拟实用程序类,那么应该使用单例,因为可以替换对象引用

    通过更改单例实例引用(静态变量)或在客户端使用对象字段。例如

     private SomeUtility someUtility = SomeUtiltiy.INSTANCE;
    
     public void someMethod(...){
        // Can be replaced by changing the someUtility reference
        someUtility.doSomething(....); 
    
        // A static call like 
        // SomeUtility.doSomething(...);
        // can not be easily replaced.
     }
    

    静态方法调用很难替换。一些测试框架,如
    powermock
    通过重写客户端字节码来提供支持。但我认为这些框架是为了支持对糟糕的遗留代码进行单元测试而设计的。如果您需要powermock来编写新代码,您应该重新考虑您的设计。

    无论何时您看到Java或任何OO语言中的实用程序类,它都可能表明您遗漏了一些东西。也就是说,模型中有一些对象需要存在。这是一个考虑这可能是什么的机会,