UPDATE 12/8: Reply to the comment
Question: what if FileReader is something very simple, like Logging, to be there in every class. Do you suggest that I take the same approach?
It depends.
There is something you might think about before doing massive refactoring.
If I move FileReader outside, do I have a suitable class that can read from a file and provide the result for each individual class that they need?
Besides simplifying class testing, do I get any other benefits?
Do i have time
If any of the answers is NO, you better not do this.
However, we can still break the dependency between all classes and FileReader with minimal changes.
From your question and comment, I assume that your system uses FileReader as a global link to read material from the properties file, and then provide it to the rest of the system.
This technique is also featured in a great book by Michael Persa: Effectively Work with Legacy Code .
Step 1. Delegate the FileReader static methods to the instance.
Change
public class FileReader { public static FileReader getMemberOne() {
For
public class FileReader { private static FileReader singleton = new FileReader(); public static String getMemberOne() { return singleton.getMemberOne(); } public String getMemberOne() {
Thus, the static methods in FileReader no longer know how getMemberOne()
Step 2. Extract the interface from 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() {
We retrieve the entire method in AppProperties , and the static instance in FileReader now uses AppProperties .
Step 3. Static Setter
public class FileReader implements AppProperties { private static AppProperties singleton = new FileReader(); public static void setAppProperties(AppProperties prop) { singleton = prop; } ... ... }
We opened the seam in FileReader. By doing this, we can set the base instance of the change in FileReader , and it will never notice.
Step 4. Cleaning
FileReader now has two functions. One of them is the read files and provides the result, the other is a global link for the system.
We can separate them and give them a good name. Here is the result:
END.
After that refactoring when you want to test. You can install mock AppProperties in GlobalAppProperties
I think this refactoring will be better if all you want to do is break the same global dependency in many classes.