0

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

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

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

4

7 回答 7

9

没有任何其他规范,听起来你想使用一个接口:

interface Rules {
    Response processRule();
}

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

class Rules_v2 implements Rules {
    public Response processRule() { ... }
}
于 2013-02-20T16:19:54.423 回答
1

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

于 2013-02-20T16:19:58.123 回答
1

您可以使用单独的类加载器来加载同一类的不同版本……但请注意,使用类加载器真的很痛苦。

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

于 2013-02-20T16:23:09.573 回答
0

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

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

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

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

于 2013-02-20T16:21:40.897 回答
0

理想情况下,您永远不必这样做,但如果您必须维护映射到某些版本化有线接口中元素的方法,则将版本表示为语言中的值,并使用蹦床方法来保持 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);
  }
}
于 2013-02-20T16:24:19.460 回答
0

这是对 Kajetan Abt 的回答的致敬,但被升级了。

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

    }

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

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

于 2013-02-20T16:26:42.577 回答
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 框架,这样,您编写一个额外的设置类(模块),您可以在其中找出在运行时使用的最佳实现。

于 2013-02-20T16:34:46.460 回答