如何对java方法进行版本化?

时间:2013-02-20 16:17:27

标签: java

我需要修改业务规则的方法,同时保持所有先前版本的可访问性。它们所包含的类将是相同的,但每种方法中的内容将是不同的。我希望他们有相同的方法签名。调用者将知道它想要执行的版本。我也不希望在方法名称中使用_vX(如下例所示)。有一个更好的方法吗?像每个方法上的注释之类的东西会很好但是在简单的测试中似乎不可能使方法足够独特。

public class SomeSpecificRule {
     public Response processRule_v1() {
     }
     public Response processRule_v2() {
     }
}

编辑:不同方法的原因是方法中包含的逻辑可能在不同时间(主要场景)有效,但我们需要能够在任何给定的任何版本上运行时间(次要)。用于日期x1-x2的method_v1和来自日期x2-x3的method_v2将是常见的。但是,“我们应该使用哪个版本”给定日期和我想要的其他标准逻辑保持分离,以便为其他开发人员轻松创建这些类和其他方法。

7 个答案:

答案 0 :(得分:7)

没有任何其他规格,听起来你想要使用界面:

interface Rules {
    Response processRule();
}

class Rules_v1 implements Rules {
    public Response processRule() { ... }
}

class Rules_v2 implements Rules {
    public Response processRule() { ... }
}

答案 1 :(得分:1)

无法对方法进行版本控制。单个签名只能出现一次。您可以拥有具有相同方法的不同类,并通过工厂或其他方法检索它们,但您无法按照您的要求进行操作。

答案 2 :(得分:1)

您可以使用单独的classloaders来加载同一类的不同版本......但要注意,使用类加载器是一件非常痛苦的事。

我认为简单的OOP方法(如其他答案所示)可能更方便。

答案 3 :(得分:0)

或者您可以在内部进行版本控制:

processRule(..., int Version = 0)
{
switch (Version)
   //etc
}

如果您将Version == 0默认为“当前版本”,这可能相对实用吗?

我的观点是,您所谓的“业务逻辑版本”实际上是业务逻辑本身,因为您明确使用多个版本,因为您的业务需要它

答案 4 :(得分:0)

理想情况下,你永远不必这样做,但是如果你必须维护映射到某个版本化的有线界面中的元素的方法,那么将版本表示为语言中的值,并使用trampoline方法来保持API的简单性。

enum Version {
  V1,
  V2,
  V3,
  ;
}

public class ClassWithVersionedMethod {
  // Protected to allow overriding while preventing clients from calling
  // versioned methods explicitly, and to minimize clutter in the javadoc and
  // IDE-autocomplete menus.
  protected T methodV1(...) { ... }
  protected T methodV2(...) { ... }
  protected T methodV3(...) { ... }

  // Final to prevent overriding of unversioned method by accident.
  public final T method(Version v, ...) {
    switch (v) {
      case V1: return methodV1(...);
      case V2: return methodV2(...);
      case V3: return methodV3(...);
    }
    // Throw outside switch so that we get a compiler warning when
    // someone adds a member to Version.
    throw new AssertionError("Unsupported version " + v);
  }
}

答案 5 :(得分:0)

这是对Kajetan Abt答案的致敬,但却很高兴。

    public void processRule(int version)
        {
        switch (Version){
          case 1:
            executeRule1();
            break;
          case 2:
            executeRule2();
            break;
        }

    }

   //executeRule1(), executeRule2() functions declarations here

我认为这比创建新类更好,因为您试图保留所有以前版本的方法。

答案 6 :(得分:0)

基本上在其他答案中说的是:使用界面

public interface Car {
  public void start();
  public void drive();
}

如何应用以完全保持版本与代码的混乱,为每个版本创建该接口的单独实现。

public class CarV1 implements Car{
  public void drive(){}
  public void start(){}
}

public class CarV2 extends CarV1{
  @Override
  public void drive(){//--extra--}
}

public class CarNewV3 implements Car{
  public void drive(){//--new--}
  public void start(){//--new--}
}

您可以从头开始创建完整的实现类,或者扩展以前的版本以添加/覆盖某些功能。

最后,要将它们连接起来,即为了提供适当的版本,您可以使用:

工厂类,他们可以提供特定版本的实现。该类可以检查一些参数并选择使用特定版本。

public class CarFactory(){
  public static Car newCar(){
    if(year >= 2013){
      return new CarNewV3();
    }else if (year >= 2000){
      return new CarV2();
    }else{
      retrun new CarV1();
    }
  }
}

或者,使用一些DI框架,这样,你可以编写一些额外的设置类(模块),在这里你可以找出在运行时使用的最佳实现。