title: Static to non-static refactoring, can't have both?
body: <p>I have a refactoring situation that I cannot find an elegant solution for...</p>
  <p><em>Disclaimer:</em>
  Keep in mind that I am oversimplifying this example to reduce clutter, and not disclose things I am not allowed to disclose :)
  As such, please do not assume that this is the ONLY code in my giant codebase, and offer solutions that cut corners or change parts of the design that I mention cannot be changed due to outside constraints.</p>
  <p><em>The facts:</em></p>
  <p>I have a utility class, it has a bunch of static methods, they utilize a singleton resource:</p>
  <hr />
  <pre><code>public final class Utility
  {
     private static final Resource RES = Resource.getInstance();
     
     private Utility() {}  // Prevent instantiating Utility
     
     public static boolean utilMethodOne() { return RES.isSomething(); }
     public static int utilMethodTwo() { RES.getNumThings(); }
     ...
     public static void utilMethodInfinity() { ... }
  }
  </code></pre>
  <hr />
  <p>Utility is in a library JAR that is used by several applications in a large codebase -- let's say on the order of 10,000 calls to its static methods, e.g.:   if(Utility.utilMethodOne()) { ... }</p>
  <p>Resource is an outside class from another library JAR.</p>
  <p>Resource also has a method Resource.getInstance(String name) that will return a named instance, which may relate to a different underlying resource based on the name (internally it keeps the named resources in a Map&lt;String,Resource&gt;).</p>
  <p>Resource.getInstance() returns the equivalent of Resoruce.getInstance(&quot;&quot;), aka the default instance.</p>
  <p><em>The situation:</em></p>
  <p>The Utility needs to be enhanced to now execute against one of several resources, so my plan is to make the Utility an instantiable class with a non-static Resource member variable.  Something like this:</p>
  <hr />
  <pre><code>public final class Utility
  {
     private Resource res;
     
     public Utility(String resName)
     {
        this.res =  = Resource.getInstance(resName);
     }
     
     public boolean utilMethodOne() { return this.res.isSomething(); }
     public int utilMethodTwo() { this.res.getNumThings(); }
     ...
     public void utilMethodInfinity() { ... }
  }
  </code></pre>
  <hr />
  <p>Now all this is great, and I can start creating Utility objects that access their specified resource instead of just the default one.  However, as I mentioned, there are 10-100K method calls that are now invalid as they were calling static methods!</p>
  <p><em>The problem:</em></p>
  <p>My plan was to keep the static methods in Utility, and have them use the default instance from Resource, while adding in non-static variants for the instantiated Utility objects that use their &quot;local&quot; resource reference.</p>
  <hr />
  <pre><code>   // Best of both worlds:
     public static boolean utilMethodOne() { return RES.isSomething(); }
     public boolean utilMethodOne() { return this.res.isSomething(); }
  </code></pre>
  <hr />
  <p>Maybe I can't have my cake &amp; eat it too:</p>
  <hr />
  <pre><code>error: method utilMethodOne() is already defined in class Utility
     public static boolean utilMethodOne(String sql)
  </code></pre>
  <hr />
  <p>So it seems I am going to have to either...</p>
  <ol>
  <li>Introduce a whole new BetterUtility class for places that want to use the named-resources.</li>
  <li>Update 10,000 places to instantiate &amp; use the revised Utility object.</li>
  <li>...?  (hint: this is where your suggestions come in!)</li>
  </ol>
  <p>I really don't like 1 or 2 for a variety of reasons, so I need to ensure there is no better 3 option before settling.  Is there any way to retain a single class that can provide both the static &amp; non-static interfaces in this case?</p>
  <h1>UPDATE 2020-06-01:</h1>
  <p>I am coming to the realization that this magical option 3 doesn't exist.  So out of my original two options I think #2 is best as it's just one time &quot;just get it out of the way and be done with it&quot; type effort.  Also incorporated some of your suggestions in the design(s).</p>
  <p>So now that I have a direction on this, I am left with [hopefully only] one more key decision...</p>
  <ol>
  <li>Update all the calls to create new objects</li>
  </ol>
  <hr />
  <pre><code>// For a one-off call, do it inline
  boolean foo = new Utility(&quot;res1&quot;).utilMethodOne();
  
  
  // Or when used multiple times, re-use the object
  Utility util = new Utility(&quot;res1&quot;);
  boolean foo = util.utilMethodOne();
  int bar = util.utilMethodTwo();
  ...
  </code></pre>
  <hr />
  <p>Given the amount/frequency of usage, this seems like a whole lot of wasted efforts creating short-lived objects.</p>
  <ol start="2">
  <li>Follow the pattern that Resource itself uses, creating my own named-singleton map of Utilities (1:1 with their respectively named Resource)</li>
  </ol>
  <hr />
  <pre><code>public final class Utility
  {
     private static final Map&lt;String,Utility&gt; NAMED_INSTANCES = new HashMap&lt;&gt;();
  
     private Resource res;
  
     private Utility(String resName)
     {
        this.res = Resource.getInstance(resName);
     }
     
     public static Utility getInstance(String resName)
     {
        synchronized(NAMED_INSTANCES)
        {
           Utility instance = NAMED_INSTANCES.get(resName);
           if(instance == null)
           {
              instance = new Utility(resName);
              NAMED_INSTANCES.put(resName, instance);
           }
  
           return instance;
        }
     }
  
     public boolean utilMethodOne() { return this.res.isSomething(); }
     public int utilMethodTwo() { this.res.getNumThings(); }
     ...
     public void utilMethodInfinity() { ... }
  }
  
  
  // Now the calls can use
  Utility.getInstance(&quot;res1&quot;)
  
  // In place of
  new Utility(&quot;res1&quot;)
  </code></pre>
  <hr />
  <p>So essentially this boils down to object creation vs. a synchronization + map lookup at each usage.  Probably a little bit of premature optimization here, but I'll probably have to stick with this decision long term.</p>
  <h1>UPDATE 2020-06-29:</h1>
  <p>Didn't want to leave an &quot;Internet dead end&quot; here...
  I did eventually get <strong>all</strong> the call sites updated as described above (including option #2 from the 2020-06-01 update).  It has made it through all testing and been running in production for a week or so now in various applications.</p>