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

标签 java oop design-patterns immutability

我正在考虑重构我们的一些实用程序类(静态类)。 静态类很难测试,主要问题是它的制作 我们的代码非常紧耦合,有很多依赖。 用于重构的最佳设计模式是什么? 我考虑过使用构建器来实现不可变对象(immutable对象),但我不确定

将此代码视为 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;
    }
}

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

最佳答案

实用类反模式

人们说静态方法难以测试的原因更多是关于它如何随着时间的推移紧密耦合不相关的类,并且它降低了凝聚力 以及引入不可见的副作用这三件事比一些单元测试挥手提示重要得多

测试交互

它更多的是测试与其他代码的交互,而不是测试 static 方法本身。这就是 Java 真正需要 Functions 作为第一类对象的地方。

在大多数情况下,只有 static 方法的类绝对是一种代码味道。也有异常(exception),但这种反模式往往会被非面向对象语言的初学者和老手滥用。

规则的异常(exception)——不可变

异常主要是标记为 final 的类可能被认为是缺失 的东西,比如 StringImmutable.

拥有一个具有通用化static 方法的Strings 类并不是那么糟糕,因为String 是不可变的(没有副作用)并且您不能向 String 类添加任何内容,这样您就没有太多选择了。 Integer 等也是如此,Guava 具有此命名约定,适用于这些不可变对象(immutable对象)。

副作用

static 方法往往会引入很多副作用。获取一个对象并以某种不透明的方式操纵该对象的事情是不好的,更糟糕​​的是,当它们随后查找其他对象并根据传入的实例操纵它们时,它们混淆了正在发生的事情并且紧密耦合并且低内聚。

高内聚

紧密内聚没有耦合那么多,但它同样重要。它们是同一枚硬币的两面,忽视一面会导致另一面遭受损失。

这些静态方法应该在它们作为参数的类上,它们与这些类紧密耦合。在这种情况下,为什么它们不在 Item 类中?

一旦您添加另一个采用SomeOtherItemstatic 方法,您就间接地将不相关的类耦合在一起。

解决这个问题的最简单方法是将事物移到离它们所属的位置更近的地方,在这种情况下移至 Item 类。

工厂/提供者模式

如果你有一些东西确实是general或者因为它是final或其他原因而不能添加到一个类中的东西,使用接口(interface)和Provider 模式是使用 Factory 生成 Provider 实例的最佳方法,甚至更好。

然后你可以使用类似 Guice 的东西来注入(inject)你需要的任何实现,这取决于它是否是一个测试。

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

关于java - 在 java 中重构 Utility 类(静态类)的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30505511/

相关文章:

oop - 面向对象编程原则

java - 如何正确使用 Struts ActionForms、Value Objects 和 Entities?

PHP5 类范围怪癖

java - JCheckBox.isSelected() 线程安全吗?

java - 在 java 中使用 while 循环将用户输入转换为类似密码的星号

java - Spring批处理元数据表的问题

java - 多态性能做什么而继承不能?

php - 依赖注入(inject)太多?

Java通过多线程共享对象 - 需要设计模式

java - 从集合中选择/选择,即 mongoDB gridFS 的 block 或文件。我们可以在什么基础上做出这个决定?