我正在考虑重构我们的一些实用程序类(静态类)。 静态类很难测试,主要问题是它的制作 我们的代码非常紧耦合,有很多依赖。 用于重构的最佳设计模式是什么? 我考虑过使用构建器来实现不可变对象(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
的类可能被认为是缺失 的东西,比如 String
是 Immutable
.
拥有一个具有通用化static
方法的Strings
类并不是那么糟糕,因为String
是不可变的(没有副作用)并且您不能向 String
类添加任何内容,这样您就没有太多选择了。 Integer
等也是如此,Guava
具有此命名约定,适用于这些不可变对象(immutable对象)。
副作用
static
方法往往会引入很多副作用。获取一个对象并以某种不透明的方式操纵该对象的事情是不好的,更糟糕的是,当它们随后查找其他对象并根据传入的实例操纵它们时,它们混淆了正在发生的事情并且紧密耦合并且低内聚。
高内聚
紧密内聚没有耦合那么多,但它同样重要。它们是同一枚硬币的两面,忽视一面会导致另一面遭受损失。
这些静态
方法应该在它们作为参数的类上,它们与这些类紧密耦合。在这种情况下,为什么它们不在 Item
类中?
一旦您添加另一个采用SomeOtherItem
的static
方法,您就间接地将不相关的类耦合在一起。
解决这个问题的最简单方法是将事物移到离它们所属的位置更近的地方,在这种情况下移至 Item
类。
工厂/提供者模式
如果你有一些东西确实是general
或者因为它是final
或其他原因而不能添加到一个类中的东西,使用接口(interface)和Provider
模式是使用 Factory
生成 Provider
实例的最佳方法,甚至更好。
然后你可以使用类似 Guice
的东西来注入(inject)你需要的任何实现,这取决于它是否是一个测试。
甚至还有一个混合 Utility
模式,它可以从 Provider
注入(inject)实现,这将为您提供 static
方法的便利以及没有它的灵 active 和可维护性。
关于java - 在 java 中重构 Utility 类(静态类)的最佳方法是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30505511/