0

以前のすべてのバージョンにアクセスできるようにしながら、ビジネス ルールのメソッドを改訂する必要があります。それらが含まれるクラスは同じになりますが、各メソッドの内容は異なります。同じメソッドシグネチャを持っていることをお勧めします。呼び出し元は、実行したいバージョンを知っています。また、メソッド名に _vX を含めないことをお勧めします (以下の例のように)。これを行うより良い方法はありますか?各メソッドの注釈のようなものはいいのですが、簡単なテストでは、メソッドを十分に一意にすることはできなかったようです.

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

編集: メソッドが異なる理由は、メソッド内に含まれるロジックが異なる時点で有効になる可能性が高いためです (主なシナリオ) が、任意の時点で任意のバージョンを実行できるようにする必要があります (セカンダリ)。Dates x1-x2 で使用される method_v1 と 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

同じクラスの異なるバージョンをロードするために別のクラスローダーを使用することもできますが、クラスローダーを使用するのは非常に面倒であることに注意してください。

(他の回答で示唆されているように)単純なOOPアプローチの方が便利だと思います。

于 2013-02-20T16:23:09.573 に答える
1

メソッドをバージョン管理することはできません。1 つの署名は 1 回だけ表示できます。同じメソッドを持つさまざまなクラスを作成し、ファクトリまたはその他のメソッドを介してそれらを取得できますが、求めていることはできません。

于 2013-02-20T16:19:58.123 に答える
0

これはKajetanAbtの答えへの賛辞ですが、誇張されています。

    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

基本的に、他の回答で述べたこと: Use an Interface

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 に答える
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 に答える