静态非静态重构,不能兼有吗?

问题描述 投票:4回答:1

我的重构情况无法为...找到合适的解决方案

免责声明:请记住,我过分简化了此示例以减少混乱,并且不透露我不允许透露的内容:)因此,请不要以为这是我庞大的代码库中的唯一代码,并且要提供解决方案,这些措施可以偷工减料或更改我提到的设计部分,由于外部限制而无法更改。

事实:

我有一个实用程序类,它有很多静态方法,它们利用单例资源:


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() { ... }
}

实用程序位于一个JAR库中,大型代码库中的多个应用程序都使用该实用程序-假设对它的静态方法进行了10,000次调用,例如:if(Utility.utilMethodOne()){...}

资源是另一个库JAR的外部类。

资源也有一个方法Resource.getInstance(String name),它将返回一个命名实例,该实例可能基于名称与另一个基础资源相关(内部将命名资源保存在Map中。

[Resource.getInstance()返回等效于Resoruce.getInstance(“”),也称为默认实例。

情况:

现在需要对Utility进行增强以针对多种资源之一执行,因此我的计划是使Utility成为具有非静态Resource成员变量的可实例化类。像这样的东西:


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() { ... }
}

现在,所有这些都很棒,我可以开始创建访问其指定资源而不只是默认资源的实用程序对象。但是,正如我提到的,由于调用静态方法,现在有10-100K个方法调用无效!

问题:

我的计划是将静态方法保留在Utility中,并让它们使用Resource中的默认实例,同时为使用其“本地”资源引用的实例化Utility对象添加非静态变量。


   // Best of both worlds:
   public static boolean utilMethodOne() { return RES.isSomething(); }
   public boolean utilMethodOne() { return this.res.isSomething(); }

也许我不能也不能吃蛋糕:


error: method utilMethodOne() is already defined in class Utility
   public static boolean utilMethodOne(String sql)

所以看来我将不得不要么...

  1. 为想要使用命名资源的地方引入一个全新的BetterUtility类。
  2. 更新10,000个位置以实例化和使用修改后的Utility对象。
  3. ...? (提示:这是您提出建议的地方!)

由于种种原因,我真的不喜欢1或2,所以我需要确保在解决之前没有更好的3个选择。在这种情况下,有什么方法可以保留可以同时提供静态和非静态接口的单个​​类?

java class methods static refactoring
1个回答
0
投票
似乎您可能希望将实用程序变成一个单例映射,该映射具有相同的静态方法,该方法可以访问单例而无需为函数调用添加任何参数(就像现在一样)

单例将支持添加新资源的静态方法,然后将其添加到地图。

此外,您可以重载现有方法以接受参数资源名称,该名称将使用映射中的特定资源,否则将使用映射中的默认条目。

© www.soinside.com 2019 - 2024. All rights reserved.