在java中重构Utility类的最佳方法是什么(静态类)

Mos*_*ari 2 java oop design-patterns immutability

我在考虑重构一些实用程序类(静态类).静态类很难测试,主要问题是它的制作我们的代码非常紧密耦合,很多依赖.用于重构的最佳设计模式是什么?我想到了一个建造者的不可变对象,但我不确定

将此代码视为1我想重构

public class UtilTest {

    public static boolean  isEligibleItem(Item item){
         if(isCondition1(item)){
             return isCondition2(item);
         }

         return false;
    }

    public static  boolean  isCondition1(Item item){
        //go to service that go to the data base  
        return false;
    }

    public static boolean  isCondition2(Item item){
        //go to service that go to the data base  
        return false;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我想测试我的isEligibleItem()方法,我需要模拟转到db的2方法.我不能这样做,因为它们是静态的.我想避免使用Powermock

小智 5

效用类反模式

人们说静态方法难以测试的原因更多的是它如何将不相关的类紧密地耦合在一起,它会降低凝聚力并引入不可见的副作用.这三件事情比一些单位测试手挥手投诉更重要

测试交互

它更多的是测试与其他代码的交互,而不是测试static方法本身.这就是Java真正需要Functions作为头等对象开始的地方.

static在大多数情况下,只有方法的类绝对是代码味道.有一些例外,但这种反模式往往会被非面向对象语言的初学者和旧计时器滥用.

规则的例外 - 不可改变

唯一的例外是主要的事情,可能会被认为缺少一个标记从一个类finalStringImmutable.

拥有一个Strings具有通用static方法的类并不是那么糟糕,因为它String是不可变的(没有副作用),你不能向String类中添加任何东西,所以你没有很多选择.同样如此Integer,Guava有这个命名约定,它适用于这些不可变对象.

副作用

static方法往往会引入很多副作用.以某种不透明的方式处理对象并操纵该对象的事情是糟糕的,更糟糕​​的是,当他们查找其他对象并根据传入的实例操纵它们时,它们会混淆正在发生的事情并紧密耦合低凝聚力.

高凝聚力

紧密凝聚不像耦合那样被谈论,但它同样重要.它们是同一枚硬币的两面,而忽略一面会导致另一枚硬币遭受损失.

这些static方法应该在它们作为参数的类上,它们与这些类紧密耦合.在这种情况下,他们为什么不Item上课?

只要您添加另一个static方法,SomeOtherItem您就可以将非相关类间接耦合在一起.

修复此问题的最简单方法是将更接近它们所属的位置移到Item类中.

工厂/供应商模式

如果您确实有某些东西或某些general东西无法添加到类中,因为它是final或其他原因,使用接口和ProviderPattern是使用a Factory生成Provider实例的最佳方法甚至更好.

然后,您可以使用类似的东西Guice注入您需要的任何实现,具体取决于它是否是测试.

甚至还有一个混合Utility模式可以从一个注入的实现注入,Provider这将为您提供static方法的便利性和没有它的灵活性和可维护性.