You want to ensure reusing functionality does not have any other side effects in other places that might be using it.
Make the static instance explicit by introduce a static instance encapsulating any static state and delegate items to it. Use the instance.
Imagine you had this sort of code (below) and there’s dozens of use throughout a codebase. Static imports make it easy for people to simply increment a count, but in order to use the Counter, you have no assurance nothing else will try to use it.
public class Counter { static int totalCount; public static void count() { totalCount++; } }
The following transformations will help you keep existing clients happy:
- Introduce new method (instance level)
- Introduce global instance
- Delegate static method to new method (instance level)
- Turn static state into instance state
The final result is below (note that this code is not thread-safe and not designed for concurrent programs, but is there to demonstrate the result of the refactoring steps):
public class Counter { private static final Counter INSTANCE = new Counter(); private int totalCount; public static void count() { INSTANCE.recordCount(); } public void recordCount() { totalCount++; } }
Now we had a bit more of a complex example, but this refactoring helped us move to the right direction of using instances where possible, instead of sharing global state.