You have a class that is in a package that contains other classes that it is not related to in function.
Move the class to a more relevant package. Or create a new package if required for future use.
class org.davison.ui.TextThing class org.davison.ui.TextProcessor class org.davison.log.Logger depends on class org.davison.ui.StringUtil
class org.davison.ui.TextThing class org.davison.ui.TextProcessor class org.davison.log.Logger depends on class org.davison.util.StringUtil
Classes are often created in a packages close to where they are being used, this can make sense until the class starts to be re-used by other parts of the product. The package in question might also have just become too big. (I have a preference that my packages never have more than about 10 classes)
It is often better to move to this class to a package more related to it in form or function. This can help remove complex package level dependencies and make it easier for developers to find and re-use classes.
If there are many dependencies for the class within its own package, then Extract Class could be used first to split out the relevant parts.
Another example where is this used often is to move String resource objects into sub a res
package to simplify localization compilation.
java.lang.reflect
or the ResourceBundle
api. Also look for code that might reference this class as an absolute class literal.Lets look at the header of StringUtil
package org.davison.ui // imports public class StringUtil ...
We move the file and change the package header.
package org.davison.util // imports public class StringUtil ...
I can now compile and unit test this class in its new package. If the unit tests are in a different package class file then they might need to be updated.
I can now go on to update the dependant classes. For example here I update the import statements, I have not used a wide imports in this example but the principle is the same.
package org.davison.log // imports import org.davison.ui.StringUtils; // more imports public class Logger ...
This becomes:
package org.davison.log // imports import org.davison.util.StringUtils; // more imports public class Logger ...
Again compile and test this new class with the imports.
As mentioned before there are other ways of dynamically loading classes. You may have to look for class literals and strings constants containing the fully qualified name of the old class.
// A class literal public Class m_utils = org.davison.ui.StringUtils.class; // A dynamically loaded class public Class m_utils = Class.forName("org.davison.ui.StringUtils"); // A loaded resource bundle public ResourceBundle m_bundle = ResourceBundle.getBundle( "org.davison.ui.StringUtils");
These can be fixed using simple find and replaces, these dynamic examples will also be found using the units tests for all classes.
// A class literal, this will be found by the compiler. public Class m_utils = org.davison.util.StringUtils.class; // A dynamically loaded class public Class m_utils = Class.forName("org.davison.util.StringUtils"); // A loaded resource bundle public ResourceBundle m_bundle = ResourceBundle.getBundle( "org.davison.util.StringUtils");
One all static and dynamic cases have been dealt with, and all unit tests have run. The refactoring is complete.