更新 12/8:回答评论
问题:如果 FileReader 是非常基本的东西,比如 Logging,需要在每个类中都有。你会建议我在那里采用同样的方法吗?
这取决于。
在进行这样的大规模重构之前,您可能需要考虑一些事情。
如果我搬到FileReader
外面,我是否有一个合适的类可以从文件中读取并将结果提供给每个需要它们的类?
除了使课程更容易测试之外,我还有其他好处吗?
我有时间吗?
如果任何一个答案是“否”,那么你最好不要这样做。
但是,我们仍然可以打破所有类之间的依赖关系,并且FileReader
只需进行最小的更改。
根据您的问题和评论,我假设您的系统FileReader
用作从属性文件中读取内容的全局参考,然后将其提供给系统的其余部分。
Michael Feathers 的精彩著作《有效地使用遗留代码》中也介绍了这种技术。
步骤 1. 将静态方法委托FileReader
给实例。
改变
public class FileReader {
public static FileReader getMemberOne() {
// codes that read file.
}
}
到
public class FileReader {
private static FileReader singleton = new FileReader();
public static String getMemberOne() {
return singleton.getMemberOne();
}
public String getMemberOne() {
// codes that read file.
}
}
通过这样做,FileReader
现在的静态方法不知道如何getMemberOne()
步骤 2. 提取接口FileReader
public interface AppProperties {
String getMemberOne();
}
public class FileReader implements AppProperties {
private static AppProperties singleton = new FileReader();
public static String getMemberOne() {
return singleton.getMemberOne();
}
@Override
public String getMemberOne() {
// codes that read file.
}
}
我们将所有方法提取到 中,并在现在使用AppProperties
中的静态实例。FileReader
AppProperties
步骤 3. 静态设置器
public class FileReader implements AppProperties {
private static AppProperties singleton = new FileReader();
public static void setAppProperties(AppProperties prop) {
singleton = prop;
}
...
...
}
我们在 FileReader 中打开了一个接缝。通过这样做,我们可以设置更改底层实例,FileReader
而它永远不会注意到。
步骤 4. 清理
现在FileReader
有两个职责。一种是读取文件并提供结果,另一种是为系统提供全局参考。
我们可以将它们分开并给它们一个好的命名。这是结果:
// This is the original FileReader,
// now is a AppProperties subclass which read properties from file.
public FileAppProperties implements AppProperties {
// implementation.
}
// This is the class that provide static methods.
public class GlobalAppProperties {
private static AppProperties singleton = new FileAppProperties();
public static void setAppProperties(AppProperties prop) {
singleton = prop;
}
public static String getMemberOne() {
return singleton.getMemberOne();
}
...
...
}
结尾。
在此重构之后,无论何时要进行测试。您可以将模拟设置AppProperties
为GlobalAppProperties
我认为如果你想做的只是打破许多类中相同的全局依赖关系,这种重构会更好。